反射-动态创建对象执行方法(有了Class对象,能做什么、通过反射来动态创建一个对象、setAccessible:安全检查开头,关闭后可以访问私有属性)

上一章小结
在实际的操作中,取得类的信息的操作代码,并不会经常开发。一定要熟悉java.lang.reflect包的作用,反射机制。
如何取得属性、方法、构造器的名称,修饰符等。
复制代码
有了Class对象,能做什么?

创建类的对象:调用Class对象的newlnstance()方法
1)类必须有一个无参数的构造器。
2)类的构造器的访问权限需要足够
思考?难道没有无参的构造器就不能创建对象了吗?只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,才可以实例化操作。
步骤如下:
1)通过Class类的getDeclaredConstructor(Class ... parameterTypes)取得本类的指定形参类型的构造器
2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。3)通过Constructor实例化对象
复制代码

 

复制代码
调用指定的方法
通过反射,调用类中的方法,通过Method类完成。
通过Class类的getMethod(String name,Class...parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。

1.实例化Class   Class.forName()--->Person
2.找到sayHello()  getMethod("sayHello");--->+  sayHello() void
3.invoke() 调用方法----》+  sayHello() void

Object invoke(Object obj, Object ... args)
Object 对应原方法的返回值,若原方法无返回值,此时返回null若原方法若为静态方法,此时形参Object obj可为null
若原方法形参列表为空,则Object[] args为null
若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法。
复制代码

 

setAccessible:安全检查开头,关闭后可以访问私有属性
Method和Field、Constructor对象都有setAccessible()方法。setAccessible作用是启动和禁用访问安全检查的开关。
参数值为true则指示反射的对象在使用时应该取消Java语言访问检查。
提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true。使得原本无法访问的私有成员也可以访问
≥参数值为false则指示反射的对象应该实施Java语言访问检查

 

复制代码
package 反射;//动态创建对象,通过反射

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Text2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        //获得class对象
        Class c1=Class.forName("反射.User1");
        //构造一个对象
        try {
            //输出的值都为空,因为本质上我们调用的是无参构造器,所以我们创建类的对象必须要有一个无参构造器
       User1 user =(User1)c1.newInstance();//他给的是Object类型,但是我们知道他是什么类型的,所以这里强转成了User
        System.out.println(user);
        } catch(Exception e) {
            System.out.println("InstantiationException");
        } finally {
        }
        
        //通过构造器创建对象,没有空参构造器也可以用,因为我们是指定了构造器
       Constructor constructor= c1.getDeclaredConstructor(String.class,int.class,int.class);
         //操作对象
         User1 user1 =(User1)constructor.newInstance("开心",001,24);
         System.out.println(user1);
         
         //通过反射调用普通方法
       User1 user3 =(User1)c1.newInstance();   //对象
       //通过反射获取一个方法
      Method setName= c1.getDeclaredMethod("setName",String.class);//对象
      //invoke:激活的意思
      //参数列表:(对象,"方法的值"):方法是那个对象的,那我们就只需要传那个对象即可
     //操作方法
      setName.invoke(user3,"小怪");//给user3对象的,setName方法传递一个String的值
      System.out.println(user3.getName());
      
      //通过反射操作属性
       User1 user4 =(User1)c1.newInstance();   //对象
       Field name=c1.getDeclaredField("name");
       //操作name
       //不能直接操作私有属性,我们需要关闭程序的安全检测,通过方法/属性,把setAccessible(true),设置为true即为关闭
       name.setAccessible(true);//关闭权限检查,这样我们就可以设置私有的属性了和方法了,无关闭这个检查检查的话,我们就没有权限去修改私有的方法和属性了
       name.set(user4,"小开心");//给user4对象设置值
       System.out.println(user4.getName());
       
    }
}






//实体类:pojo,entity:来表示实体类
class User1{
    private String name;
    private int id;
    private int age;
    
    public User1(){
        
    }
    
    public User1(String name,int id,int age){
        this.name=name;
        this.id=id;
        this.age=age;
    }
    
    
    public void setName(String name){
        this.name=name;
    }
    
    public String getName(){
        return name;
    }
    //------------------
    
     public void setId(int id){
        this.id=id;
    }
    
    public int getId(){
        return id;
    }
    
    //--------------
       public void setAge(int age){
        this.age=age;
    }
    
    public int getAge(){
        return age;
    }
    
    //输出方法
    public String toString(){
        return "User{"+"name="+name+"id="+id+"age="+age+"}";

}
}
复制代码

 

posted @   hollg  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示