java反射

来源:互联网 发布:手机电池修复软件下载 编辑:程序博客网 时间:2024/05/20 09:06

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中的反射三(反射机制深入—工厂设计模式)

http://www.tuicool.com/articles/bmeYFf

0 0
原创粉丝点击