反射补充

反射补充

//获取类的信息
public class Test{
    public static void main()throws ClassNotFoundException{
        User user = new User();
        Class c1 = user.getClass();
        System.out.println(c1.getName());//获得包名+类名
        System.out.println(c1.getSimpleName);//获得类名
        
        Filed[] fields = c1.getFields();//只能获取public属性
        for(Field field : fields){
            System.out.println(field);
        }
     
        //=============  
        Filed[] fields = c1.getDeclaredFields();//找到所有属性
        for(Field field : fields){
            System.out.println(field);
        
         //获得指定属性的值 
         Field name = c1.getDeclaredField("name") ;
            System.out.println(name);
        } 
        
        //获得类的方法
        Method[] methods = c1.getMethods();
        for (Method method : methods){
            System.out.println(method);//打印输出User类中的public方法,还包括父类Object类中的所有方法:toString\getName\getAge\setName\setAge\Object.getClass\Object.hashCode等等
        }
        
        Method[] methods2 = c1.getDeclaredMethods();
        for (Method method : methods2){
            System.out.println();//仅打印输出了User类中的所有方法(包括private方法)
        }
        
        //获得指定方法getMethod(name:"getName",...parameterTypes:null),括号内的参数类型很重要,这是因为重载的机制,若不加以限定,就较难达到预期效果。
        Method getName = c1.getMethod("getName",null);
        Method setName = c1.getMethod("setName",String.class);//setName方法需要一个String类型的参数
    }
    
    //获得构造器,两者区别如上
    Constructor[] constructors = c1.getConstructors();
    constructors = c1.getDeclaredConstructors();
    
    //获得指定的构造器
    Constructor constructor = c1.getConstructor(String.Class,Int.Class)
}

通过上述能够了解到,Class对象可以获取该类的方法、属性,甚至是构造方法,不仅如此,它还可以创建类的对象

调用Class对象的newInstance()方法创建对象。(两个条件:1、类必须有一个无参构造。2、类的构造器的访问权限足够)

Class.newInstance实际上是调用了无参构造器。我们在创建有参对象时可以通过调用有参构造器,对其输出参数来创建一个有参对象。

其实通过newInstance()方法无参构造对象后便可以使用对象的方法增改参数,下面进行一个知识扩展

Class c1 = Class.forName("com.Demo.User");
User user = (User) c1.newInstance();
System.out.println(user);//此时因为是通过newInstance()方法,调用的无参构造,所以输出的对象{user,null,0}

Constructor constructor = c1.constructor(String.Class,int.Class);
User user2 =(User) constructor.newInstance("Peter",25);

//通过创建的对象调用方法
//invoke(对象,参数)方法,激活的方法,括号内传递激活方法目标对象、方法参数
User user3 = c1.newInstance();
Method setName = c1.getMethod(setName,String.Class);
setName.invoke(user3,"Peter");
System.out.println(user3.getName);

采用invoke的方法便可以从外部向内创建输入任意的方法名以及参数来执行方法

//通过反射来操作属性
User user4 = (User)c1.newInstance();
Field name =c1.getDeclaredField("name");

//不能直接操作私有属性,需要关闭程序的安全检测,属性或方法的setAccessible(true).
name.setAccessible(true);
name.set(user4,"Peter");
    System.out.println(user4.getName());
posted @ 2020-11-22 13:35  何安生  阅读(53)  评论(0)    收藏  举报