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)将对象引用压入栈;

 

posted @ 2016-01-09 20:48  chenyizh  阅读(138)  评论(0)    收藏  举报