Day 8 : 补Java语言基础

it2023-07-03  67

包、JAR、JWS

部署应用程序的三种情况 1 本机:JAR 2 远程:Servlets 3 介于上述两者之间:Java Web Start(JWS)、RMI.java & .class .java文件是我们编写代码的文件,运行时需要先编译,编译完成后会生成.class文件,我们真正执行的是.class文件中的main()函数。你可以通过-d来选择编译后的文件放在哪里,并且如果没有路径文件夹,它会自动创建(IDEA会自动帮忙管理): //编译,生成xxxx.class %javac -d ../classes xxxx.java //执行 %cd ../classes %java xxxx JAR 为了管理这些.class文件,使用jar工具对这些类文件进行包装,生成一个JavaARchive(JAR)文件。JAR里有一个manifest.txt文件,里面说明里这些类里面哪些有main()方法。一般在本机的部署都是使用JAR来管理。 生成、启动JAR的命令行如下: //manifest.txt里面需要这一行:“Main-Class:xxxx" //生成JAR %jar -cvmf manifest.txt app1.jar *.class //启动JAR %java -jar app1.jar 包 为了避免类重名,我们可以将类打包再包装成JAR。比如JavaAPI中的java.net.socket等。但是同样我们也要避免包之间的同名,我们可以将domin放到包名称前,来标注这个包是我们项目(或公司)编写的,如:com.xhpjava.projects.Chart。 包管理规则如下(与IDEA默认的管理方式不同): 编译、构建、解压带包的JAR操作命令行在下列出,JAR内部将只有.class文件以及一个META-INF文件夹,内部有MANIFEST.MF文件(内容与manifest.txt类似): //编译包结构文件 %javac -d ../classes com/xhpjava/xxxx.java //执行 %cd ../classes %java com.xhpjava.xxxx //生成JAR,只要指定com目录就可以了 %jar -cvmf manifest.txt packxxxx.jar com //列出jar %jar -tf packxxxx.jar //解压jar %jar -xf packxxxx.jar Java Web Start 用户可以通过网页上的某个链接来启动Java Web Start的应用程序,一旦下载后,它就能独立与浏览器来执行。即Java Web Start应用程序是通过网络来发布的。 其工作方式如下:首先客户端点击JWS的应用程序的链接(.jnlp文件);其次Web服务器发送.jnlp给客户端,客户端打开JWS的helper app读取.jnlp并请求.jar文件;最后Web发送.jar文件给客户端,客户端调用指定的main()来启动程序。 创建与部署JWS暂时跳过,等需要的时候再看。

远程部署 & RMI

RMI

RMI可以调用不同堆(机器)上的对象。

RMI的原理是通过客户端辅助设施(stub)和服务器辅助设施(skeleton),来进行通讯,使客户端成为真正服务的代理(proxy),也就是说客户端只需要提供信息,而操作服务由服务器来完成。

RMI是有风险的会抛出异常。

RMI的通信协议一般是JRMP或IIOP,前者为java到java的远程调用,后者可以服务java到其他类型的远程方法。

创建远程服务总共有下面几个步骤:

创建Remote的接口 这个远程接口定义了用户端可以调用的Remote方法。这个接口是一个标记性质的接口,自身没有方法,其中声明的方法都要抛出RemoteException,并且返回值是primitive主数据类型或Serializable。 public interface MyRemote extends Remote { public String sayHello() throws RemoteException; } 实现Remote方法 真正执行的类,是客户端的调用对象。 //继承UnicastRemoteObject来处理远程服务对象 public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote { //实现Remote接口中声明的方法 public String sayHello() { return "Server says, 'Hey'"; } //你可以编写更多的方法,但需要在接口中声明 //声明RemoteException的无参数构造函数 public MyRemoteImpl() throws RemoteException { } //向RMI registry注册服务,客户端靠注册名字进行查询 public static void main(String[] args) { try { //创建远程对象 MyRemote service = new MyRemoteImpl(); //第一个参数为注册的名称,提供给客户端查询 Naming.rebind("Remote Hello", service); } catch (Exception ex) { ex.printStackTrace(); } } } 用rmic产生stub和skeleton;启动RMI registry,用户从此处获得代理(获得stub对象;启动远程服务。(在终端行不通?) %rmic MyRemoteImpl %rmiregistry %java MyRemoteImpl

在创建完远程服务器后,客户端需要取得stub对象来调用需要的服务,其代码如下:

public class MyRemoteClient { public static void main (String[] args) { new MyRemoteClient().go(); } public void go() { try { //这里要做类型转换,lookup是一个静态方法,需要输入IP地址和注册名称 MyRemote service = (MyRemote) Naming.lookup("rmi://127.0.0.1/Remote Hello"); String s = service.sayHello(); System.out.println(s); } catch (Exception ex) { ex.printStackTrace(); } } }

Servlets

servlet 是完全在HTTP服务器上运行的Java程序。servlet 是用来处理用户交互的网页程序,例如用户提交一些表单信息给服务器,servlet就可以把特定结果在网页上进行输出。JSP和servlet的区别:JSP是Java Server Pages,Web服务器最终也会将JSP转化为servlet。servlet是编写具有HTML输出的类,而JSP是写出带有Java程序的网页,JSP的好处在于更容易编写。(后面需要额外学习更多JSP和servlet的知识)

EJB & jini

EJB(Enterprise JavaBeans)是更加安全、并发、具有其他功能的RMI,但是会有点笨重。 jini看不太懂之后再说QAQ。


小知识点

assert断言

静态嵌套类 是一种静态的内部类,也具有静态属性:不需要外层的实例可以直接使用。

存取权限和修饰符 1 public : 任何代码都可以公开存取。 2 protected : 不常用,运行不在同一个包的子类存取。 3 defalut : 默认的种类,只允许同一个包的类别进行存取。 4 private : 只有同一类的程序代码可以存取,比如Cat不能存取Dog的private部分。

多维数组

枚举(enum) 简单用法:

public enum Members { JERRY, BOBBY, PHIL }; Members ifName = Members.BOBBY; switch (ifName) { case JERRY: System.out.print("make it sing "); case PHIL: System.out.print("go deep "); case BOBBY: System.out.print("Cassidy! "); }

还可以加入构造函数方法和变量:

public class HFJEnum { enum Names { JERRY("lead guitar") { //覆盖sings方法 public String sings() { return "plaintively"; } }, BOBBY("rhythm guitar") { public String sings() { return "hoarsely"; } }, PHIL("bass"); private String instrument; //构造方法,需要传入instrument参数 Names(String instrument) { this.instrument = instrument; } //定义可调用的方法 public String getInstrument() { return this.instrument; } public String sings() { return "occasionally"; } } public static void main(String[] args) { //每个enum都有内置的values(),用在for循环中 for(Names n : Names.values()) { System.out.print(n); System.out.print(", instrument: " + n.getInstrument()); System.out.println(", sings: " + n.sings()); } } }
最新回复(0)