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 公开抽象的。而且不能有构造方法。抽象类就比较自由了,和普通的类差不多,可以有抽象方法也可以没有,可以有正常的方法,也可以没有。
 
让类具有比较和拷贝的能力:class xxx implements Cloneable, Compareable

================

一、内存管理

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的用途:

  • 锁定方法,防止被继承类修改。
  • 写出可以在运行时被确定的代码,从而可以内嵌调用。

 内部类:成员内部类、静态内部(嵌套)类、方法内部类、匿名内部类 。

成员内部类:

class Outer {
class Inner{}
}
编译上述代码会产生两个文件:Outer.class和Outer$Inner.class。
 
方法内部类:
把类放在方法中。
(1)、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
(2)、方法内部类对象不能使用该内部类所在方法的非final局部变量
class Outer {
public void doSomething(){
final int a =10;
class Inner{
public void seeOuter(){
System.out.println(a);
}
}
Inner in = new Inner();
in.seeOuter();
}
public static void main(String[] args) {
Outer out = new Outer();
out.doSomething();
}
}
匿名内部类:
当程序中使用匿名内部类时,在定义匿名内部类的地方往往直接创建该类的一个对象。匿名内部类的声明格式如下:
new ParentName(){
...// 内部类的定义
}
很方便,直接在new的时候实现一个接口或一个类。
静态内部类:
静态内部类中可以定义静态或者非静态的成员。
静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类仅能访问外部类的静态成员和方法。
class Outer{
static class Inner{}
}
class Test {
public static void main(String[] args){
Outer.Inner n = new Outer.Inner();
}
}
在静态方法中定义的内部类也是StaticNested Class,这时候不能在类前面加static关键字,静态方法中的StaticNested Class与普通方法中的内部类的应用方式很相似,它除了可以直接访问外部类中的static的成员变量,还可以访问静态方法中的局部变量,但是,该局部变量前必须加final修饰符。
 
 
@Override的用法:
编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。
 
二、异常
JAVA里的异常机制是,程序执行过程中遇到异常,则该方法向上级方法传递异常,直到main方法。
异常分为捕获异常与未捕获异常。所谓捕获异常即必须处理的异常,若某代码段可能出现某捕获异常必须处理,未出现必须不处理。不能在一个正常的代码段后catch一个捕获异常。否则无法通过编译。(至于哪些是捕获异常,编译的时候编译器会提醒你,否则会无法通过编译)
try..catch..finally,catch与finally不能都省略。finally一般情况下在try和catch执行后都会得到执行(即使在try或catch中有return语句也会得到执行)。
关于抛出异常:声明的时候是throws ...,代码里是throw ...,可向上级方法传递异常。刚才说了,某代码段可能出现某捕获异常则必须处理,可以以try..catch..finally的方式处理(自己处理),也可以直接在函数声明处一以void f() throws ...{}处理(上级处理)。
throws关键字的最大好处是:在方法中不处理任何的异常,而交给被调用处处理。
声明的时候有捕获异常,则必须用以上用以上两种方法处理,throws或try...catch...finally...
声明的时候throws xx,代码里可以没有throw xx,遇到xx异常,则隐式抛出异常,有throw xx,则显示抛出异常。
关于异常的博客资料:http://taohui.iteye.com/blog/1222431

代码点是针对Unicode字符集而言的,一个代码点就是一个编号而已,表示一个数字映射一个字符。实际上在Unicode层面理论上说,并没有涉及如何在计算机存储 代码单元则是对字符集编码层面,这才涉及到如何在计算机存储的层面,例如一个字符对应的代码点的值,应该用几个字节存储?要不要使用代理?变长的规则? 这导致了几个方案,UTF-8/UTF-16/UTF-32。都是其中方案。代码单元指的是该方案最少需要多少个字节编码一个Unicode字符。UTF-8的代码单元是1个字节,UTF-16的代码单元是两个字节,UTF-32是4个字节。在Java中,字符内部使用的是UTF-16,所以才是两个字节。

posted @ 2016-06-09 23:40  我在地狱  阅读(484)  评论(4编辑  收藏  举报