Java语言特性之反射

 

反射机制

        Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。当然反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。

        Java反射机制主要提供下面几种用途:
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法
反射的基石——Class类
所有的类文件都有共同属性,所以可以向上抽取,把这些共性内容封装成一个类,这个类就叫Class(描述字节码文件的对象)。
    Class类中就包含属性有field(字段)、method(方法)、construction(构造函数)。
        而field中有修饰符、类型、变量名等复杂的描述内容,因此也可以将字段封装称为一个对象。用来获取类中field的内容,这个对象的描述叫Field。同理方法和构造函数也被封装成对象Method、Constructor。要想对一个类进行内容的获取,必须要先获取该字节码文件的对象。该对象是Class类型。
 

Class类描述的信息:类的名字,类的访问属性,类所属于的包名,字段名称的列表,方法名称的列表等。每一个字节码就是class的实例对象。如:classcls=Data.class;

Class类中的方法
        static Class forName(String className)
返回与给定字符串名的类或接口的相关联的Class对象。
        Class getClass()
返回的是Object运行时的类,即返回Class对象即字节码对象
        Constructor getConstructor()
返回Constructor对象,它反映此Class对象所表示的类的指定公共构造方法。
        Field getField(String name)
返回一个Field对象,它表示此Class对象所代表的类或接口的指定公共成员字段。
        Field[] getFields()
返回包含某些Field对象的数组,表示所代表类中的成员字段。
        Method getMethod(String name,Class… parameterTypes)
返回一个Method对象,它表示的是此Class对象所代表的类的指定公共成员方法。
        Method[] getMehtods()
返回一个包含某些Method对象的数组,是所代表的的类中的公共成员方法。
        String getName()
以String形式返回此Class对象所表示的实体名称。
        String getSuperclass()
返回此Class所表示的类的超类的名称
        boolean isArray()
判定此Class对象是否表示一个数组
        boolean isPrimitive()
判断指定的Class对象是否是一个基本类型。
        T newInstance()
创建此Class对象所表示的类的一个新实例。

获取构造方法:
1)得到这个类的所有构造方法:如得到上面示例中Person类的所有构造方法
2)获取某一个构造方法:
3、创建实例对象:
1)通常方式:Person p = new Person(“lisi”,30);
2)反射方式:Person p= (Person)con.newInstance(“lisi”,30);

Field类代表某个类中一个成员变量
方法
Field getField(String s);//只能获取公有和父类中公有
Field getDeclaredField(String s);//获取该类中任意成员变量,包括私有
setAccessible(ture);
如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。
set(Object obj, Object value);//将指定对象变量上此Field对象表示的字段设置为指定的新值。
Object get(Object obj);//返回指定对象上Field表示的字段的值。

Method类
方法
Method[] getMethods();//只获取公共和父类中的方法。
Method[] getDeclaredMethods();//获取本类中包含私有。
Method getMethod("方法名",参数.class(如果是空参可以写null));
Object invoke(Object obj ,参数);//调用方法
如果方法是静态,invoke方法中的对象参数可以为null。

 

import java.lang.reflect.*;

public class CreateClassDemo {  
    public static void main(String[] args) throws Exception {  
        createPersonClass();  
        getPersonField();
    }  
    //通过Class对象创建类实例方法  
    public static void createPersonClass() throws Exception{  
        //获取Person类的Class对象  
        String className="cn.itheima.Person";  
        Class clazz=Class.forName(className);  
        //通过newInstance方法获取类的无参构造函数实例  
        Person p=(Person)clazz.newInstance();  
        System.out.println(p);
    }
    //通过Constructor对象来创建类实例方法  
    public static void createPersonClass_2() throws Exception{  
        //获取Person类的Class对象  
        String className="cn.itheima.Person";  
        Class clazz=Class.forName(className);  
        //Class clazz=Person.class;  
              
        //获取指定构造函数的类实例  
        Constructor con=clazz.getConstructor(String.class,int.class);  
        Person p=(Person) con.newInstance("lisi",30);  
        System.out.println(p.toString());  
    }
    //获取Person对象的成员变量  
    public static void getPersonField() throws Exception{     
    //如果想要给该变量赋值,必须先要有对象。  
        Class clazz=Class.forName("cn.itheima.Person");  
//        Person p=(Person)clazz.newInstance();    
        Person p = (Person) clazz.getConstructor(String.class,int.class).newInstance("wode",13);
        //获取所以的成员变量  
        Field[] fs=clazz.getFields();  
        for(Field f:fs){  
        	System.out.print("A:::::::");
            System.out.println(f);  //私有成员变量未打印,不在getfields()方法的返回值中
        }  
        //获取指定的成员变量  
        Field fage=clazz.getField("age");  
        Field fname=clazz.getDeclaredField("name");                
        //显示改变后的值  
        fage.set(p, 20);  
        System.out.println(fage.get(p));                
        //暴力访问私有变量  
        fname.setAccessible(true);  
        fname.set(p, "zhangsan");  
        System.out.println(fname.get(p));  
    }  
} 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值