• java反射


    反射

    反射就是解析对象,然后直接使用对象的东西,而不是通过变量去调用,反射比较消耗资源,有虚拟机规定,如果某个对象的反射使用的达到15次,就会将这个对象创建成具有反射特色的变量,方便直接调用其函数。

    反射获取对象的属性(字段、方法、注解等)

    注解类

    package Reflection;
    
    import static java.lang.annotation.ElementType.TYPE;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    import java.lang.annotation.Documented;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    import java.lang.annotation.Repeatable;
    
    @Documented
    @Retention(RUNTIME)
    @Target(TYPE)
    @Inherited
    @Repeatable(CustomDescriptions.class)
    public @interface CustomDescription {
    	String description() default "";
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    package Reflection;
    
    import static java.lang.annotation.ElementType.TYPE;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    import java.lang.annotation.Documented;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    @Documented
    @Retention(RUNTIME)
    @Target(TYPE)
    @Inherited
    public @interface CustomDescriptions {
    	CustomDescription[] value();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    对象类

    package Reflection;
    
    @CustomDescription(description="基类")
    @CustomDescription(description="人")
    public class Person {
    	
    	private String Name;
    	
    	public String getName() {
    		return Name;
    	}
    	
    	public void setName(String name) {
    		Name = name;
    	}
    	
    	public String PersonPublicMethod(String str)
    	{
    		return str;
    	}
    	
    	public Person(String name) {
    		Name = name;
    	}
    
    	public String PersonPrivateMethod(String str)
    	{
    		return str;
    	}
    
    	public Person() {
    		super();
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    package Reflection;
    
    @CustomDescription(description="学生")
    @CustomDescription(description="人")
    public class Student extends Person {
    	public String StudentId;
    
    	public String getStudentId() {
    		return StudentId;
    	}
    
    	public void setStudentId(String studentId) {
    		StudentId = studentId;
    	}
    	
    	public String StudentPublicMethod(String str)
    	{
    		return str;
    	}
    	
    	private String StudentPrivateMethod(String str)
    	{
    		return str;
    	}
    	
    	public Student(String name, String studentId) {
    		super(name);
    		StudentId = studentId;
    	}
    	
    	private Student(String name) {
    		super(name);
    		StudentId="123456";
    	}
    	
    	public Student() {
    		
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    ##字符串例子
    Class.Forname获取到对象。

    Class clazz = null;
    		//类名.class
    		clazz = String.class;
    		System.out.println(clazz);
    		//对象.getClass()
    		clazz = "ReflectionTest".getClass();
    		System.out.println(clazz);
    		//Class.forName(全类名)
    		clazz = Class.forName("java.lang.String");
    		System.out.println(clazz);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    获取方法

            Class clazz = Class.forName("包路径");//包路径,而不是.class,哈哈哈哈哈
            Method method=null;
            Method[] methods=null;
    
            methods = clazz.getMethods();
            for(Method mth:methods){
                System.out.print(mth.getName()+" ");
            }
            System.out.println();
    
            method = clazz.getMethod("StudentPublicMethod",String.class);
            System.out.print(method.getName()+" ");
            System.out.println();
    
            methods = clazz.getDeclaredMethods();
            for(Method mth:methods){
                System.out.print(mth.getName()+" ");
            }
            System.out.println();
    
            method = clazz.getDeclaredMethod("StudentPrivateMethod",String.class);
            System.out.print(method.getName()+" ");
            System.out.println();
    
            Object obje = clazz.newInstance();
            method.setAccessible(true);
            String result=(String) method.invoke(obje,"inputParams");
            System.out.println(result);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    字段获取

              Class clazz = Class.forName("Reflection.Student");
    //      System.out.println("---------getDeclaredFields---------");
            Field[] fields = clazz.getDeclaredFields();
            for(Field field: fields){
                System.out.print(field.getName()+" ");
            }
            System.out.println();
            System.out.println("---------getFields---------");
            fields = clazz.getFields();
            for(Field field: fields){
                System.out.print(field.getName()+" ");
            }
            System.out.println();
    
            System.out.println("---------getDeclaredField---------");
            Field field = clazz.getDeclaredField("StudentId");
            field.setAccessible(true);
            System.out.println(field.getName());
    
            System.out.println("---------getField--------");
    
            field = clazz.getField("StudentId");
            System.out.println(field.getName());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    字段使用

    Class clazz = Class.forName("Reflection.Person");
    		Person person = new Person("CYW");
            //获取私有字段的值
            Field field = clazz.getDeclaredField("Name");
            //由于是私有字段,需要使用setAccessible(true)
            field.setAccessible(true);
            Object val = field.get(person);
            System.out.println(val);
            //改变私有字段的值
            field.set(person, "ivan");
            System.out.println(person.getName());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    构造函数

            String className = "Reflection.Student";
    //        Class clazz = (Class) Class.forName(className);
    //
    //        //指定成父类之后实际还是获取子类的构造函数
    //        Constructor [] constructors =
    //                (Constructor[]) Class.forName(className).getConstructors();
    //
    //        for(Constructor constructor: constructors){
    //            System.out.println("getConstructors:"+constructor);
    //        }
    //
    //        Constructor []  constructorsa =
    //                (Constructor[]) Class.forName(className).getDeclaredConstructors();
    //
    //        for(Constructor constructor: constructorsa){
    //            System.out.println("getDeclaredConstructors:"+constructor);
    //        }
    //
    //
    //      //通过getConstructor获取公有构造函数
    //        Constructor constructor = clazz.getConstructor(String.class, String.class);
    //        System.out.println("getConstructor:"+constructor);
    //        Student obj = constructor.newInstance("cyw", "123456");
    //        System.out.println(obj.getName());
    //
    //        //通过getDeclaredConstructor获取私有构造函数
    //        constructor = clazz.getDeclaredConstructor(String.class);
    //        System.out.println("getDeclaredConstructor:"+constructor);
    //        //对于私有构造函数在初始化之前要设置setAccessible(true)
    //        constructor.setAccessible(true);
    //        obj = constructor.newInstance("cyw");
    //        System.out.println(obj.getName());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    注解

     String className = "Reflection.Student";
            Class<Student> clazz = (Class<Student>) Class.forName(className);
    		CustomDescriptions  customDescriptions =clazz.getAnnotation(CustomDescriptions.class);
    		for(CustomDescription h: customDescriptions.value()){
    			System.out.println("description:" + h.description());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    其他方法

    //2.通过对象名
    //这种方式是用在传进来一个对象,却不知道对象类型的时候使用
    Person person = new Person();
    clazz = person.getClass();
    System.out.println(clazz);
    //上面这个例子的意义不大,因为已经知道person类型是Person类,再这样写就没有必要了
    //如果传进来是一个Object类,这种做法就是应该的
    Object obj = new Person();
    clazz = obj.getClass();
    System.out.println(clazz);
    //3.通过全类名(会抛出异常)
    //一般框架开发中这种用的比较多,因为配置文件中一般配的都是全类名,通过这种方式可以得到Class实例
    String className="Reflection.Person";
    clazz = Class.forName(className);       
    System.out.println(clazz);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    基于Springboot+Vue实现前后端分离商城管理系统
    Failed at the node-sass@4.13.1 postinstall script.
    华为云云耀云服务器L实例评测|Git 私服搭建指南
    LINE Verda Programming Contest (AtCoder Beginner Contest 263) A~E 题解
    上传ipa到appstore最简单的方法
    pytorch -- torch.nn.Module
    海外仓物流有哪些优缺点
    拦截器和过滤器
    JZ63 买卖股票的最好时机(一)
    DPU — 功能特性 — 存储系统的硬件卸载
  • 原文地址:https://blog.csdn.net/beidideshu/article/details/133418650