浅谈反射中获取反射、属性成员、方法以及构造对象的方法

1.获取反射的方法

获取反射Class有三种方法

public class Student {
    private String name;
    private Integer age;
}


public class StudentFanTest {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.zjh.Fanshe.Student");//根据Class.forName来获取
       
        Class<Student> studentClass = Student.class;//根据类名.class来获取
        
        Student s=new Student();
        Class<? extends Student> aClass1 = s.getClass();//根据类对象来获取

        System.out.println(aClass==studentClass);//输出结果为true
        System.out.println(aClass==aClass1);//输出结果为true
        System.out.println(aClass);//打印出地址值
    }
}

值得注意的是,这里的aClass、aClass1、studentClass打印出来的地址值相同,这说明一个类的字节码只会被加载一次  

2.通过反射创建实体类

我们可以通过newInstance来创建类对象,值得注意的是两次输出结果并不相同,这说明多次创建相同的类对象会得到不同的地址值(相当于直接new Stusdent多次)

public class StudentFanTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<Student> aClass = (Class<Student>) Class.forName("com.zjh.Fanshe.Student");
        Class<Student> studentClass = Student.class;
        Student s=new Student();
        //通过反射类得到的类对象
        Class<? extends Student> aClass1 = s.getClass();

        Student student1 = aClass.newInstance();//通过newInstance来创建类对象
        Student student2 = aClass.newInstance();
        System.out.println(student1);
        System.out.println(student2);
    }
}

3.获取属性成员对象

获取到的属性成员一般用Field类对象形式存在

而获得Field属性对象的方法有以下四种

1、getDeclaredField(String name);//获取本类中指定属性名的Field

2、getDeclaredFields();//获取本类中所有的属性对象,并返回一个数组

3、Class.getField(String name);//获取本类以及父类中指定的public属性对象

4、getFields();//获取本类以及父类中所有的public属性对象,并返回一个数组

public class Student {

    private String name;
   
    public Integer age;

}

public class StudentFanTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {

        Class<Student> aClass = (Class<Student>) Class.forName("com.zjh.Fanshe.Student");
        

        Student student = aClass.newInstance();

        Field age = aClass.getDeclaredField("age");//获取age属性对象
        age.set(student,100);//括号里第一个是类名,第二个是传入的参数
        System.out.println(student);//输出:Student{name = null, age = 100}
        System.out.println(age.getType());//获取参数类型,输出:class java.lang.Integer
        
        Field name = aClass.getDeclaredField("name");//获取name属性对象
        name.setAccessible(true);//设置允许访问私有属性
        name.set(student,"王小明");
        System.out.println(student);//输出:Student{name = 王小明, age = 100}

与此同时,我们可以通过 属性对象名.set(类名,参数)  来对指定类中的属性赋值,也可以通过get.Type来获得该参数的类型

值得注意的是,给private类参数赋值时要通过.setAccessible(true)来设置允许访问私有属性

4.获取方法类对象

获取方法类对象的方法有四种

1、getDecTaredMethods() //获取本类中所有的方法,返回值为一个数组

2、getDeclaredMethod(string name,类... parameterTypes)//获取本类中指定的方法

3、getMethods()//获取本类以及父类中public的方法

4、getMethod(string name,类... parameterTypes) //获取本类以及父类中指定的方法

public class MethodGroup {
    public String meth01(){
        System.out.println("this is 01");
        return "meth01";
    }
    public String meth01(int age){
        System.out.println("this is 01");
        return "meth01"+age;
    }
    public String meth02(int age){
        System.out.println("this is 02");
        return "meth02"+age;
    }
    public String meth03(){
        System.out.println("this is 03");
        return "meth03";
    }
}

public class MethodTest {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException {
        Class<MethodGroup> methodGroupClass = MethodGroup.class;
        MethodGroup methodGroup = methodGroupClass.newInstance();

        /**
         * 获取本类中所有的Method方法对象
         */
        Method[] declaredMethods = methodGroupClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);//输出每个Method
        }

        Method meth01 = methodGroupClass.getMethod("meth01", int.class);
        System.out.println(meth01);//输出指定的Method

    }
}

5.Method类中常用的方法

常用的方法主要有:

invoke(): 执行该方法体。

getAnnotation(注解.class) 获取属性上的注解对象

public class MethodGroup {
    public String meth01(){
        System.out.println("this is 01");
        return "meth01";
    }
    @MyZhuJie(value = 101)
    public String meth01(int age){
        System.out.println("this is 01");
        return "meth01"+age;
    }
    public String meth02(int age){
        System.out.println("this is 02");
        return "meth02"+age;
    }
    public String meth03(){
        System.out.println("this is 03");
        return "meth03";
    }
}


public class MethodTest {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<MethodGroup> methodGroupClass = MethodGroup.class;
        MethodGroup methodGroup = methodGroupClass.newInstance();

        Method meth01 = methodGroupClass.getMethod("meth01", int.class);//获得指定的方法

        Object invoke = meth01.invoke(methodGroup, 10);//输出:this is 01
        System.out.println(invoke);//输出:meth0110

        MyZhuJie annotation = meth01.getAnnotation(MyZhuJie.class);//拿到该方法上的注解
        System.out.println(annotation.value());//拿到该方法注解的参数值:101
    }
}

6.获取构造对象的方法以及常用的方法

1、getConstructors() //方法返回当前和父类(以及父类的父类)的所有public构造函数,返回值为一个数组。
2、getDeclaredConstructors()  //方法返回当前类的所有声明的构造函数,返回值为一个数组。
3、getConstructor(Class...  parameterTypes) //方法返回当前和父类(以及父类的父类)指定的public构造函数。
4、getDeclaredConstructor(Class...  parameterTypes) 方法返回当前类指定的构造函数。

public class ConstructorGroup {
    public ConstructorGroup() {
        System.out.println("Hellow");
    }
    public ConstructorGroup(int age) {
        System.out.println("Hellow"+age);
    }
    public ConstructorGroup(String name) {
        System.out.println("Hellow"+name);
    }
}

public class ConstructorGroupTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<ConstructorGroup> constructorGroupClass = ConstructorGroup.class;
        Constructor<?>[] declaredConstructors = constructorGroupClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);//得到当前类所有的构造函数
        }
        Constructor<ConstructorGroup> declaredConstructor = constructorGroupClass.getDeclaredConstructor(int.class);//得到指定的有参构造
        declaredConstructor.newInstance(2023);//执行构造函数,输出:Hellow2023

        Constructor<ConstructorGroup> declaredConstructor1 = constructorGroupClass.getDeclaredConstructor();//得到当前类的无参构造
        declaredConstructor1.newInstance();执行构造函数,输出:Hellow
    }
}

拿到构造函数之后,我们可以通过.newInstance();来执行该构造函数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值