java中创建对象时其实不是通过类直接创建的,如果你想要使用Test类,在java中JVM首先加载Test.java文件的字节码文件Test.class(也就是编译后的文件),当JVM(java虚拟机)加载字节码文件后,自动为该类创建自己的class对象,在通过class对象创建你以后要创建的对象
例如:Test t1=new Test(); Test t2=new Test(); 我们都知道java中 == 是比较两个对象的内存地址,t1.getClass()==t2.getClass();返回是true,证明他们是一个class对象创建出来的。那么可Class对象的意义就是标志一个类了,Class类为我们提供了很多方法,比如反射技术常用到的Class.forName(“包.类”);这样可以获取一个类的Class对象。
例如:Test类在org.abc这个包里,那么可以用Class.forName(“org.abc.Test”);这样就返回一个Test类的class对象,拿到这个对象接下来可以做很多事,调用这个类的方法,属性,构造方法等,具体你去研究下反射技术。
针对一种数据类型的Class转换,比如String.class,int.class,类.class等
Class参数,就是让你传一种Class对象进去。比如String.class,int.class,类.class等
Test.class==t1.getClass();返回true,怕有误解,说明一下类和对象都可以获取class对象的。并且这个对象是一个对象,因为一个类对应自己的class对象。
其实任何一个类,都会有一个Class对象与这个类对应,在这个Class对象中,保存着实例化该类时所需要的基本信息,A.class 其实返回的是一个类A的Class对象,贴一个小代码演示一下:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 得到类名(不包含包名)
System.out.println(String.class.getSimpleName());// String
// 得到类的全名称(包含所在的包名)
System.out.println(String.class.getName());// java.lang.String
System.out.println(Test.class.getName());// Test
}
}
获取Calss对象的方式
主要有三种:
第一种:通过Class.forName(“类的全名称”)获取,用这个方法,最常见的应该是应用于JDBC注册驱动的时候用到的
try {
Class.forName("oracle.jdbc.driver.OracleDriver");// 注册驱动
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
第二种:通过已经实例化的对象获取,getClass()方法获取
第三种:通过类名.class获取
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test = new Test();
System.out.println(test.getClass());// class Test
System.out.println(Test.class);// class Test
}
}
还在网友博客上看到一段比较不错的代码:贴之
class Initable{
static final int staticFinal2 = ClassInitialization.rand.nextInt( 100 );
static {
System.out.println( " Initialization Initable");
}
}
class Initable2{
static int staticNoFinal=147;
static {
System.out.println( " Initialization Initable2");
}
}
class Initable3{
static int staticNoFinal = 74;
static {
System.out.println("Initialization Initable3");
}
}
public class ClassInitialization {
public static Random rand = new Randdom( 47 );
public static void main(String[] args){
Class initable = Initable. class ; // 不会引起初始化
System.out.println("after creating Initable reference");
System.out.println(Initable.staticFinal); // 引用编译器常量不会引起初始化
System.out.println(Initable.staticFinal2); // 引起初始化
System.out.println(Initable2.staticNoFinal); // 引用非编译期常量会引起初始化
Class initable3 = Class.forName( " Initable3 " ); // 默认会引起初始化
System.out.println("after creating Initable3 reference");
System.out.println(Initable3.staticNoFinal); // 前面已经初始化此处不用再初始化
}
}
如果一个static final值是编译期常量,那么对该值的引用无需对其所在类进行初始化;若仅仅是static和final但不是编译期常量,则会引发初始化其类。若是引用一个static值则要进行链接并对其所在类进行初始化。
下面这系列博客写的不错
java中的反射一(Class类的认识)
java中的反射二(Class类的作用)
java中的反射三(反射机制深入—获得类的结构)
java中的反射四(反射机制深入—对类的操作)
java中的反射五(反射机制深入—对数组的操作)
java中的反射六(反射机制深入—静态代理,动态代理及cglib动态代理)
java中的反射三(反射机制深入—工厂设计模式)