Java的运行
包结构
一、不带包名的类如何编译
1.没有中文的java文件
public class A {
public static void main(String[] args) {
System.out.println("TY");
}
}
命令:
javac A.java
java A
输出结果:
2.带中文的java文件
public class A {
public static void main(String[] args) {
System.out.println("你好吗");
}
}
a)
错误:编码GBK的不可映射字符
b)
错误:编译成功,但是输出是乱码
原因分析
我们需要了解javac和java命令是什么样的过程。 javac是java compiler的命令,是将.java文件编译成.class文件的过程。我们需要先将文件读入内存,才能进行编译。 读入内存需要知道文件的编码格式,才能正确的将文件读取。java源文件的编码,是UTF-8。而java编译器默认的字符集可以通过如下代码查看。System.out.println(Charset.defaultCharset());
结果输出是GBK;
问题:
为什么我们通过IDE就能编译通过。
通过IDE,不可能分开java文件编码和java compiler的编码格式的,文件设置成什么编码,编译器都会知道,就会用什么编码来解析。原生的javac不会这样,它只会按照默认的系统编码来编,这个时候如果文件编码不同,就出现这个问题了。
知道了原因,怎么解决,两种解决方案,最终目的是为了文件编码和解码字符集相同
1)
如果文件是UTF-8编码的,我们使用-encoding UTF-8 来显式指定为UTF-8的编码格式。
2)
如果是使用的Windows记事本保存为ANSI,使用其他的高级文本编辑器(notepad++等)写的另存改格式。
二、带包名的java类怎么编译
代码:
package org.ty;
public class Demo {
public static void main(String[] args) {
System.out.println("TY");
}
}
编译运行:
我们会发现编译成功,但运行报错“错误:找不到或无法加载主类A”。
原因分析:
java A
有包的java程序,需要用完整包名来执行
由于我们没有指定classpath,jvm准备在当前路径下查找Demo.class来装载,找了一圈没找到(确实有个Demo类,但是Demo类的完整路径是ty.Demo,所以不是这个),报错找不到或无法加载主类。
java ty.Demo
有包的java程序,文件路径中必须包含包名,并以包名结尾
jvm看了一下有包,于是将包转换为路径,也就是期望在D:/ty文件夹下,找到Demo.class文件进行装载。也没找到。
如果有包,java命令必须在包的上层目录执行完整路径名(完全限定名),上例中Demo.class的完全限定名是ty.Demo。如果在D盘下,有一个A.java,包路径为aaa.bbb.ccc,必须在D盘下,执行java aaa.bbb.ccc.A才行,此处的“在D盘下”,暂时可以看做直接在D盘下,也可以通过-cp指定到D盘下。
解决方案
a)
我们可以使用-d . 来让编译器以当前路径为基准,自动创建包路径,这个-d .放在前面,放在后面都可以
这个-d 可以将文件编译到指定目录下。
b)
假设我们在D盘下创建一个aa的目录,然后执行javac -d aa A.java,效果如下。
使用-classpath指定包的上级目录
使用-classpath(或者 -cp,简写,意思相同)指定.class的目录,使用相对路径,绝对路径都可以,这个目录直接通到ty的上级即可。
我们可以通过-classpath指定.class在哪个根目录下,然后从这个目录拼接上包路径来构成完整路径。
三、引入其它自定义类
1).引入自定义类
准备一个非默认的包,让A引用B。
package pack;
public class B {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void showMyName(){
System.out.println("my name is " + this.getName());
}
}
package ty;
import pack.B;
public class A {
public static void main(String[] args) {
B b = new B();
b.setName("abc");
b.showMyName();
}
}
然后将A和B都放入D盘根目录,使用javac -d . 编译A.java
解决方案一:
都编译解决方案二:
首先,java程序会将被引用的类也打包的。
然后,如果类是相互引用并且不同包的,一定要按照包的路径放好,保持包定义和文件结构同步。
我们新建mypack和pack目录,将A.java丢到pack目录下,将B.java丢到ty下。
四、命令行传参(mian函数)
代码
public class Average {
public static void main(String[] args) {
String one = args[0];
String two = args[1];
String three = args[2];
double int_One = Double.valueOf(one).doubleValue();
double int_Two = Double.valueOf(two).doubleValue();
double int_Three = Double.valueOf(three).doubleValue();
double average = (int_One + int_Two + int_Three) / 3;
System.out.println("平均数为:"+average);
}
}
先用javac编译
然后运行
java Average 45 25 36
PS:java是运行java文件的命令,Average是Java文件名,45 25 36是要往main函数传入的参数。