Java反射基本操作

一、定义

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

    JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

    在面向对象的世界里万事万物皆对象,类也是对象,是java.lang.Class的实例对象。我们创建一个类的实例对象可以通过new关键字创建比如:User user = new User()。new对象是静态加载类,在编译时刻就得加载所有可能使用的类,当我们不想在编译时刻加载所有的类,而是在运行时候需要哪个就动态的加载哪个比如:Class.froName(“类的全称”)。

二、用法

(一) 场景

    1.在运行时判断任意一个对象所属的类。

    2.在运行时构造任意一个类的对象。

    3.在运行时判断任意一个类所具有的成员变量和方法。

    4.在运行时调用任意一个对象的方法。

    5.生成动态代理。

    6.获取泛型信息。

    7.获取注解信息。

    8.获取配置文件信息。

(二) 如何使用

    1. Class对象的获取(类类型,描述其他类所具有的这些特性)。

try{       
    // 类的.class(最安全/性能最好)属性(不会自动初始化该Class对象),任何一个类都一个隐含的静态成员变量  
    Class c1 = User.class;  
  
    // 已知该类的对象通过getClass方法  
    Class c2 = user.getClass();  
  
    // 运用Class.forName(String className)动态加载类,className需要是类的全限定名(最常用)。
    Class c3 = Class.forName(“business.User”);    
  
    // 我们完全可以通过类的类类型(一个类只有一个类类型)创建该类的实例对象  
    User user = (User)c1.newInstance()  
  
}catch(ClassNotFoundExpcetion e){   
    e.printStackTrace();   
}  

    2.从Class类获取信息(Class类提供了大量的实例方法来获取该Class对象所对应的详细信息,Class类大致包含如下方法,其中每个方法都包含多个重载版本) 。

     1)Constructor<T>getConstructor(Class<?>... parameterTypes)。

     2)Method getMethod(String name,Class<?>... parameterTypes)。

     3)Field getField(String name)。

     4)Method Constructor Field这些类都实现了java.lang.reflect.Member接口,程序可以通过Method对象来执行相应的方法,通过Constructor对象来调用对应的构造器创建实例,通过Filed对象直接访问和修改对象的成员变量值。

    3.创建对象

      1)使用Class对象的newInstance()方法来创建该Class对象对应类的实例(这种方式要求该Class对象的对应类有默认构造器)。

      2)先使用Class对象获取指定的Constructor对象, 再调用Constructor对象的newInstance()方法来创建该Class对象对应类的实例(通过这种方式可以选择指定的构造器来创建实例)。

    4.访问成员变量

      1)通过Class对象的的getField()方法可以获取该类所包含的全部或指定的成员变量Field,Filed提供了如下两组方法来读取和设置成员变量值。

       PS:getDeclaredXxx方法可以获取所有的成员变量,无论private/protected。

      2)getXxx(Objectobj): 获取obj对象的该成员变量的值,此处的Xxx对应8中基本类型,如果该成员变量的类型是引用类型,则取消get后面的Xxx。

      3)setXxx(Objectobj, Xxx val): 将obj对象的该成员变量值设置成val值.此处的Xxx对应8种基本类型,如果该成员类型是引用类型,则取消set后面的Xxx。

    5.调用方法

      1)当获取到某个类对应的Class对象之后,就可以通过该Class对象的getMethod来获取一个Method数组或Method对象,每个Method对象对应一个方法,在获得Method对象之后,就可以通过调用invoke方法来调用该Method对象对应的方法。

public class MethodDemo1(){  
    public static void main(String[] args){  
        // 要获取print方法就是获取类的信息,要先获取类的类类型  
        A a1 = new A();  
        Class c = a1.getClass();  
        /* 
         *获取方法由方法名和参数决定 
         *getMethod获取的是public方法 
         *getDeclaredMethod自己声明的方法 
         */  
        try{      
             //Method m = c.getMethod(“print”, new Class[]{int.class, int.class});  
             Method m = c.getMethod(“print”, int.class, int.class);  
  
             // 方法的反射操作是作用于m对象来进行方法的调用达到和a1.print调用的效果相同   
             // a1.print(10,10); 
             // 如果方法有参数则放回具体参数,没有则放null  
             Object o = m.invoke(a1, 10, 10);  // 输出20
  
        } catch (Exception e){  
            e.printStackTrace();    
        }  
    }  
}  
  
class A(){  
    public void print(int a, int b){  
        System.out.println(a+b);  
    }  
  
    public void print(String a, String b){  
        System.out.println(a.toUpperCase()+”,”+b.toLowerCase());  
    }  
}  

三、Java反射了解集合泛型的本质

 

public class MethodDemo2(){  
    public static void main(String[] args){  
        ArrayList list = new ArrayList();  
        ArrayList<String> list1 = new ArrayList<String>();  
  
        Class c1 = list.getClass();  
        Class c2 = list.getClass();  
        System.out.printlf(c1 == c2);  
        //反射的操作都是在编译以后  
   
        /* 
         *返回结果为true则说明编译以后集合的泛型是去泛型化的; 
         *集合的泛型是为了防止输入错误,java的泛型只在编译阶段有效,编译以后无效                         
         */  
        try{  
            Method e = c2.getMethod(“add”,Object.class);  
            e.invoke(list1,10);  
            System.out.println(list1.size());  
            //会发现,size=1说明此时泛型失效了,并且注意list1此时不能用for循环遍历  
  
        }catch(Exception e){  
            e.printStackTrace();  
        }  
    }  
}  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值