java的重修之路
https://www.cnblogs.com/zuoxiaolong/p/life53.html
javac Source.java
javac类似于make,javac总是在当前目录查找文件
当Source.java内使用了其它类,如abc.class,javac会自动查找abc.class,未找到时则自动查找abc.java文件进行编译(如果abc.java比abc.class新,javac会重新编译)
一个Java源文件最多只有一个公共类,源文件的名称必须和public修饰的类的类名完全一致(区分大小写)
没有public类时,源文件名随意
有多少个类(包含匿名内部类,成员内部类等),生成多少个.class文件
java ClassName
java在类路径中查找类,默认的类路径为.;%JAVA_HOME%\lib(包含.当前目录),如果设置了类路径但不包含“.”目录,程序可以通过编译但不能运行。运行时库文件(rt.jar,以及在jre/lib和jre/lib/ext目录下的一些其它的JAR文件)会被自动搜索,不必显式地列在类路径中。
加载ClassName后,会对类进行静态初始化,再从该类的main方法开始执行。以下不包含main方法的类运行时打印完Hello, World!后报错“main is not defined”,可通过添加System.exit(0);解决。
public class Hello { static { System.out.println("Hello, World!"); } }
注意:将类放入包中后,javac、java应当从基目录运行。
代码点:与一个编码表中的某个字符对应的代码值
Unicode代码点分为17个级别,
第一个代码级别是基本的多语言级别,代码点从U+0000 ~ U+FFFF,其中包含了经典的Unicode代码
其余的16个附加级别,代码点从U+10000 ~ U+10FFFF,其中包含了一些辅助字符。
UTF-16编码采用不同长度的编码表示所有Unicode代码点。
在基本的多语言级别中,每个字符采用16位来表示,通常被称为代码单元;辅助字符采用一对连续的代码单元进行编码。
这样构成的编码值一定落入基本的多语言级别中空闲的2048字节内,通常被称为替代区域[U+D800~U+DBFF为第一个代码单元,U+DC00~U+DFFF为第二个代码单元]
代码点是针对Unicode字符集而言的,一个代码点就是一个编号而已,表示一个数字映射一个字符。实际上在Unicode层面理论上说,并没有涉及如何在计算机存储 代码单元则是对字符集编码层面,这才涉及到如何在计算机存储的层面,例如一个字符对应的代码点的值,应该用几个字节存储?要不要使用代理?变长的规则? 这导致了几个方案,UTF-8/UTF-16/UTF-32。都是其中方案。 代码单元指的是该方案最少需要多少个字节编码一个Unicode字符。UTF-8的代码单元是1个字节,UTF-16的代码单元是2个字节,UTF-32是4个字节。在Java中,字符内部使用的是UTF-16,所以才是两个字节。
main方法任何对象进行操作。每个类都可以有一个main方法,这是一个对类进行单元测试的技巧。java className将执行该类的main方法。
一个类可以使用所属包中的所有类,以及其他包中的public类
import与C++的include没有任何联系
没有import同样可以使用类,如java.util.Date
java中的package和import类似于C++中的namespace和using
import可导入类的静态方法与静态域:import static java.lang.System.*;就可以直接使用类的静态方法和静态域
Object类是所有类的超类,包含函数
boolean equals():判断是否具有相同引用
int hashCode():默认返回对象的存储地址
String toString():""+x空字符串连接一个对象,将调用x.toString()方法,System.out.print(x)输出对象也会调用x.toString()方法。
Class getClass() :返回类对象
xxx clone():返回拷贝后的引用
反射机制
获得Class对象:主要有三种方法:
(1)Object-->getClass
(2)任何数据类型(包括基本的数据类型)都有一个“静态”的class属性
(3)通过class类的静态方法:forName(String className)(最常用)
3、创建实例:通过反射来生成对象主要有两种方法:
(1)使用Class对象的newInstance()方法来创建Class对象对应类的实例。
Class<?> c = String.class; Object str = c.newInstance();
(2)先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建对象,这种方法可以用指定的构造器构造类的实例。
//获取String的Class对象 Class<?> str = String.class; //通过Class对象获取指定的Constructor构造器对象 Constructor constructor=c.getConstructor(String.class); //根据构造器创建实例: Object obj = constructor.newInstance(“hello reflection”);
接口和抽象类的异同
1、都不能被实例化。
2、接口的实现类和抽象类的子类只有全部实现了接口或者抽象类中的方法后才可以被实例化。
不同点:
1、接口只能定义抽象方法不能实现方法,抽象类既可以定义抽象方法,也可以实现方法。
2、单继承,多实现。接口可以实现多个,只能继承一个抽象类。
3、接口强调的是功能,抽象类强调的是所属关系。
4、接口中的所有成员变量 为public static final, 静态不可修改,当然必须初始化。接口中的所有方法都是public abstract 公开抽象的。而且不能有构造方法。抽象类就比较自由了,和普通的类差不多,可以有抽象方法也可以没有,可以有正常的方法,也可以没有。
================
一、内存管理
java里的声明分引用与基本数据类型。
数组:
java里new一个对象数组为 person[] A; A = new person[4]; person[0] = new person();
第一句声明了1个A数组引用变量,指向为null。第二句让A指向一个长度为4的数组内存,数组元素类型是person引用类型,值为null,此时并没有分配内存。所以才有第三句,第三句是真正意义上的分配内存。
java里new多维数组为 int[][] a; a = new int[4][]; a[0] = new int[4];
第一句声明了1个二维数组引用变量,指向为null。第二句声明让a指向一个长度为4的数组内存,数组元素是一维数组引用类型,值为null,此时并没有分配内存。第三句分配了一个长度为4的一维数组,因为数组元素是int,所以变量自动填补为0。(如果把int改为person,则到这里还不够,还需要继续new,为每个person分配内存)。
实例变量与类变量:
父子实例的内存控制:方法会覆盖,变量不不会被覆盖。
一个父类引用指向一个子类时,当用该引用调用方法 引用.方法(),调用的是实际类型的方法(子类方法);当用该引用调用变量时 引用.变量,调用的是声明类型的变量(父类变量)。
类型转换只能在继承层次内进行,在将超类转换成子类时,应该用instanceof进行检查。
final修饰符:
很多情况下,final修饰的变量会被当做宏替换处理。子类若能访问到父类的final方法,则不能对final方法进行重写。
final的用途:
- 锁定方法,防止被继承类修改。
- 写出可以在运行时被确定的代码,从而可以内嵌调用。
内部类:成员内部类、静态内部(嵌套)类、方法内部类、匿名内部类 。
成员内部类:
代码点是针对Unicode字符集而言的,一个代码点就是一个编号而已,表示一个数字映射一个字符。实际上在Unicode层面理论上说,并没有涉及如何在计算机存储 代码单元则是对字符集编码层面,这才涉及到如何在计算机存储的层面,例如一个字符对应的代码点的值,应该用几个字节存储?要不要使用代理?变长的规则? 这导致了几个方案,UTF-8/UTF-16/UTF-32。都是其中方案。代码单元指的是该方案最少需要多少个字节编码一个Unicode字符。UTF-8的代码单元是1个字节,UTF-16的代码单元是两个字节,UTF-32是4个字节。在Java中,字符内部使用的是UTF-16,所以才是两个字节。