Java学习小结
1、一切皆对象,String s; 创建的只是引用,并不是对象;一旦创建了一个引用,就希望它能与一个新的对象相关联,String s = new String("asdf");
特例:基本类型;这些类型,Java采用C++相同的方法,不用new来创建变量,而是创建一个并非是引用的变量,直接存储"值"并置于堆栈中;
2、Java数组
java中可以将数组赋值给另一个数组,其实真正做的只是复制一个引用;
如果创建非基本类型数组,那么你就创建了一个引用数组,直到通过创建新对象并把对象赋值给引用,初始化才结束;
Integer[] a = new Integer[50]; <- 只是一个引用数组
a[i] = rand.nextInt(500); <- 创建对象并赋值给引用
初始化对象数组两种方式:
1)Integer[] a = {new integer(1),new Integer(2),3}; //3-自动装箱
2)Integer[] b = new Integer[]{new Integer(1),4};
3、方法调用(静态方法、重载、重写)
Class文件的编译过程中不包含传统编译中的链接步骤,一切方法调用在Class文件中存储的都只是符号引用,而不是方法在实际运行时内存中的入口地址(直接引用)
1) 解析:如果方法的调用版本在运行期是不可改变的,那么在类加载的解析阶段,会将该目标方法的符号引用转化为直接引用;
符合该条件的有静态方法、私有方法、实例构造器、父类方法,编译器使用invokestatic和invokespecial指令处理这些方法调用;
public class StaticResolution{
public static void sayHello(){
System.out.println("hello world");
}
public static void main(String[] args){
StaticResolution.sayHello();
}
}
Code:
Stack=0,Locals=1,Args_size=1
0:invokestatic #31; //Method sayHello
3:return
2) 静态分派:所有依赖静态类型来定位方法执行版本的分派动作称为静态分派,典型应用是方法重载;
Human man = new Man(); 『Human』称为变量的静态类型,『Man』称为变量的实际类型
实际类型变化:man = new Woman(); 由 Man 变化为 Woman
静态类型变化:sayHello( (Man)man ); 由 Human 变化为 Man
在编译阶段,Javac编译器会根据参数的静态类型决定使用哪个重载版本;
public class Overload {
static abstract class Human{}
static class Man extends Human{}
static class Woman extends Human{}
public void sayHello(Human guy){
System.out.println("hello,guy!");
}
public void sayHello(Man man){
System.out.println("hello,man!");
}
public void sayHello(Woman woman){
System.out.println("hello,woman!");
}
public static void main(String[] args){
Human man=new Man();
Human woman=new Woman();
Overload ol=new Overload();
ol.sayHello(man);
ol.sayHello(woman);
}
}
运行结果:
hello,guy!
hello,guy!
3) 动态分派:在运行期根据实际类型确定方法执行版本的分派过程称为动态分派
依靠invokevirtual指令的多态查找过程:
1、找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C;
2、如果在类型C中找到与常量中的描述符和简单名称都相符的方法,则进行访问权限校验,通过则返回这个方法的直接引用,如果不通过,抛出异常;
3、否则,按照继承关系从下往上依次对C的各个父类进行步骤2的搜索和验证过程;
public class DynamicDispatch {
static abstract class Human{
protected abstract void sayHello();
}
static class Man extends Human{
protected void sayHello(){
System.out.println("man say hello");
}
}
static class Woman extends Human{
protected void sayHello(){
System.out.println("woman say hello");
}
}
public static void main(String[] args){
Human man=new Man();
Human woman=new Woman();
man.sayHello();
woman.sayHello();
man=new Woman();
man.sayHello();
}
}
运行结果:
man say hello
woman say hello
woman say hello
4、对象访问方式:使用句柄和直接指针


5、Java对象创建过程:
1)堆分配内存空间,将该空间内容置0; 2)执行出现于字段定义处的初始化动作; 3)调用构造函数; 4)将对象引用压入栈;
浙公网安备 33010602011771号