类实例化
实例化类的四种途径:
1.new操作符
2.调用Class或者java.lang.reflect.Constructor对象的newInstance()方法
3.现有对象的clone();
4.java.io.ObjectInputStream类的getObject()方法
6.隐含创建:
保存命令行参数的String对象;
每一个命令行参数都会有一个String对象的引用,把它们组织成一个String数组
并作为一个参数传递到每个程序的main方法中
7.jvm装载的每一个类型 暗中实例化Class对象代表这个类型
8.jvm装载了在常量池中包含CONSTANT_String_info入口的类的时候,
会创建新的String对象的实例表示这些常量字符串
把方法区中的Constatn_string_info入口转换成一个堆中的String实例的过程
是常量池解析过程的一部分
9。执行包含字符串连接操作符的表达式产生对象
如果这样的字符串不是一个编译时常量 用于中间处理的String和StringBuffer对象会在计算表达式的过程中创建
所有在对象的类中和它的超类声明的变量 包括隐藏的实例变量 都要分配内存
一旦虚拟机为新的对象准备好了堆内存 立即把实例变量初始化为默认的初始值
随后为实例变量赋予正确的初始值
根据创建对象的方法不同 jvm使用三种技术:
clone()创建的 jvm把原来被克隆的实例变量中的值拷贝到新对象
对象通过ObjectInputStream的readObject()调用反序列化
jvm通过输入流中读入的值来初始化非暂时性的实例变量
否则 调用对象的实例初始化方法
实例初始化方法把对象的实例初始化为正确的初始值
java 编译器为它编译的每个类都至少生成一个实例初始化方法
针对源代码中每个类的构造方法 java编译器产生init()方法
如果类没有明确地声明任何构造方法 编译器默认产生一个无参构造方法
仅仅调用父类的无参构造方法
init可能包含三种:
1.调用另一个init()方法 实现对任何实例变量的初始化 构造方法体的代码
2.如果构造方法通过明确调用同一个类的另一个构造方法
对应的()方法由两部分构成
一个同类的init方法的调用
实现了对应构造方法的方法体的字节码
3.如果构造方法不是通过this()调用开始 对象不是Object ()由三部分组成
一个超类的()方法调用
任意实例变量初始化方法的字节码
实现了对应构造方法的方法体的字节码
4.如果构造方法没有使用this() 并且这个类是Object
Object没有超类 init()方法不能通过调用超类的init()方法开始
class Example6{
private int width =3;
Example6{
this(1);
System.out.println(Example6(),width="+width);
}
Example6(int width){
this.width = width;
system.out.prntln(Example6(int ) width="''')
}
Example6(String msg)
{
super();
system.out.println("Example6(String),width"+width);
sytem.out.println(msg); }
public static void main(String[] args{
Strignmsg = "The Agapathus is also know as Lily Of the Nile."
Example6 one = new Example6();
Example6 two = new Example6(2);
Example6 three = new Example6(msg);
}
}
}
除了Object之外的每个类 不管是同类还是直接超类
()方法必须从另一个()方法调用开始
不允许捕捉由它们锁调用的方法抛出的异常
如果子类的()方法调用一个被意外终止的超类的init方法
那么子类的Init()方法 必须同样被意外终止