1.Class 的newInstance()方法
Class的newInstance()方法是实现“虚拟构造器”的一种途径,虚拟构造器允许声明:“我不知道你的确切类型,但是无论如何要正确地创建你自己”。
package com.zhetang.t14;
interface HasBatteries{}
interface Waterproof{}
interface Shoots{}
class Toy{
Toy(){}
Toy(int i){}
}
class FancyToy extends Toy implements HasBatteries,Waterproof,Shoots{
FancyToy() {
super(1);
}
}
public class ToyTest {
static void printInfo(Class cc){
System.out.println("Class name:"+cc.getName()+" is interface? ["+cc.isInterface()+"]");
System.out.println("simple name: " + cc.getSimpleName());
System.out.println("Canonical name:" +cc.getCanonicalName());
}
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("com.zhetang.t14.FancyToy");//需要完整的路径包括包名
} catch (ClassNotFoundException e) {
System.out.println("Can't not found FancyToy");
System.exit(1);
}
printInfo(c);
for(Class face : c.getInterfaces()){
printInfo(face);
}
Class up = c.getSuperclass();
Object obj = null;
try {
obj = up.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("----");
printInfo(obj.getClass());
}
}
注意:
Class.forName(“com.zhetang.t14.FancyToy”);//需要完整的路径包括包名
使用newInstance()来创建的类,必须带有默认的的构造器。比如Toy(){},否则会抛出InstantiationException异常(反射调用的)
2.类字面常量
java提供了类字面常量来生成对Class的引用,如:FancyToy.class这样做不仅简单,而且安全,因为它在编译时就会受到检查(因此不需要置于try语句中)
注意:当使用”.class”对象来对Class引用时,不会自动地初始化该Class对象。
import java.util.Random;
class Inital {
static final int staticFinal = 47;
static final int staticFinal2 = ClassA.rand.nextInt(100);
static {
System.out.println("Initalzing Initable");
}
}
class Initable2{
static int staticNonFinal = 74 ;
static {
System.out.println("Initializing Initable2");
}
}
class Initable3{
static int staticNonFinal = 147;
static{
System.out.println("Initializing Initable3");
}
}
public class ClassA{
public static Random rand = new Random(47);
public static void main(String[] args) throws ClassNotFoundException {
Class initable = Inital.class;
System.out.println("---After creating Initable ref--");
System.out.println(Inital.staticFinal);
System.out.println(Inital.staticFinal2);
System.out.println(Initable2.staticNonFinal);
Class initl3 = Class.forName("com.zhetang.t14.Initable3");
System.out.println("After creating Initable3 ref");
System.out.println(Initable3.staticNonFinal);
}
}
结果:
---After creating Initable ref--
47
Initalzing Initable
58
Initializing Initable2
74
Initializing Initable3
After creating Initable3 ref
147
初始化有效地实现了尽可能的“惰性”。从对initable引用的创建中可以看到,仅使用.class语法来获得对类的引用不会引发初始化,但是,为了产生Class引用,Class.forName()立即就进行了初始化,就像在对initable3引用的创建中所看到的。
如果一个static final值是“编译期常量”,就像Initable.staticFinal那样,那么这个值不需要对Initable类进行初始化就可以获取。但是,如果只是将一个域设置为static和final的,还不足以确保这种行为。