美文网首页
反射基础

反射基础

作者: 陈柴盐 | 来源:发表于2018-11-26 23:40 被阅读0次

材料准备

public class Student {

            private int id;
            private String name;
            private int age;

            public Student(int id, String name, int age) {
                this.id = id;
                this.name = name;
                this.age = age;
            }


            public Student(String name) {
                this.name = name;
            }

            public Student() {
            }

            public int getId() {
                return id;
            }

            public void setId(int id) {
                this.id = id;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public int getAge() {
                return age;
            }

            public void setAge(int age) {
                this.age = age;
            }

            @Override
            public String toString() {
                return "Student{" +
                        "id=" + id +
                        ", name='" + name + '\'' +
                        ", age=" + age +
                        '}' + "\n";
            }


            @Override
            public boolean equals(Object o) {
                if (this == o) {return true;}
                if (o == null || getClass() != o.getClass()) {return false;}

                Student student = (Student) o;

                if (id != student.id) {return false;}
                if (age != student.age) {return false;}
                return name != null ? name.equals(student.name) : student.name == null;
            }

            @Override
            public int hashCode() {
                int result = id;
                result = 31 * result + (name != null ? name.hashCode() : 0);
                result = 31 * result + age;
                return result;
            }


            /*方法*/
        public void method1(String string) {
            System.out.println(string);
        }

        public void method2(String string,int i) {
            System.out.println(string+i);
        }

        public void method3(String string,Integer integer,String s) {
            System.out.println(string+integer+s);
        }
}

Class类

获取Class对象

  1. 通过类名.class获取
  2. 通过对象名.getClass()获得
  3. 通过Class类的静态方法forName("类全名字符串")获得
Class c1 = Student.class;

Student s =  new Student();
Class c2 = s.getClass();

Class c3 = Class.forName("xxx.Student");

Constructor类

类中的每一个构造方法都是一个Constructor类的对象

通过Class对象获取Constructor对象

  1. Constructor getConstructor(Class... parameterTypes)//根据参数获取构造器
  2. Constructor[] getConstructors()//获取所有的构造方法

常用方法

  1. T newInstance(Object... initargs)//创建对象

代码示例:

public static void main(String[] args) throws Exception {
        Class<Student> studentClass = Student.class;

        //获取无参构造方法
        Constructor<Student> constructor = studentClass.getConstructor();
        System.out.println("constructor = " + constructor);
        Student student = constructor.newInstance();
        System.out.println("student = " + student);
        System.out.println("=============================");
    
        //获取有参构造方法
        Constructor<Student> constructor1 = studentClass.getConstructor(String.class);
        System.out.println("constructor1 = " + constructor1);
        Student student1 = constructor1.newInstance("权属");
        System.out.println("student1 = " + student1);
        System.out.println("=============================");
    
        //获取有参构造方法2
        Constructor<Student> constructor2 = studentClass.getConstructor(int.class, String.class, int.class);
        System.out.println("constructor2 = " + constructor2);
        Student student2 = constructor2.newInstance(1, "内容", 18);
        System.out.println(student2);
        System.out.println("=============================");
    
        //获取所有构造方法
        Constructor<?>[] constructors = studentClass.getConstructors();
        for (Constructor<?> subConstructor : constructors) {
            System.out.println(subConstructor);
        }

    }

输出结果

constructor = public junit和反射和注解.反射.Student()
student = Student{id=0, name='null', age=0}

=============================
constructor1 = public junit和反射和注解.反射.Student(java.lang.String)
student1 = Student{id=0, name='权属', age=0}

=============================
constructor2 = public junit和反射和注解.反射.Student(int,java.lang.String,int)
Student{id=1, name='内容', age=18}

=============================
public junit和反射和注解.反射.Student()
public junit和反射和注解.反射.Student(java.lang.String)
public junit和反射和注解.反射.Student(int,java.lang.String,int)

Method类

类中每一个成员方法都是一个Method对象

通过Class对象获取Method对象

  1. Method getMethod(String methodName, Class...param)//根据方法名和参数获取方法对象
  2. Method[] getMethods()//获取所有方法对象
  3. Method[] getDeclaredMethods()//获取不包括父类方法的独享

method类的常用方法

  1. Object invoke(Object obj,Object...args)

代码示例:

    public static void main(String[] args) throws Exception{
        Class<Student> studentClass = Student.class;

        Method method1 = studentClass.getMethod("method1", String.class);
        Method method2 = studentClass.getMethod("method2", String.class, int.class);
        Method method3 = studentClass.getMethod("method3", String.class, Integer.class, String.class);

        method1.invoke(studentClass.getConstructor().newInstance(), "你");
        method2.invoke(studentClass.getConstructor().newInstance(), "我", 1);
        method3.invoke(studentClass.getConstructor().newInstance(),"他",1,"们");

        System.out.println("=============================");

        Method[] methods = studentClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("=============================");

        //不包括父类的方法
        Method[] declaredMethods = studentClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
    }

输出结果

你
我1
他1们
=============================
public void exercise.Student.setAge(int)
public void exercise.Student.setId(int)
public int exercise.Student.getAge()
public void exercise.Student.method2(java.lang.String,int)
public void exercise.Student.method1(java.lang.String)
public void exercise.Student.method3(java.lang.String,java.lang.Integer,java.lang.String)
......

Field类

类中的每一个成员变量都是一个Field对象

Class对象中获取Field对象的方法

  1. Field getDeclaredField(String name);//根据变量名获取对应的Field对象
  2. Field[] getDeclaredFields();//获取所有的Field对象

Field类的常用方法
​ void set(Object obj, Object value)
​ void setInt(Object obj, int i)
​ void setLong(Object obj, long l)
​ void setBoolean(Object obj, boolean z)
​ void setDouble(Object obj, double d)

​ Object get(Object obj)
​ int getInt(Object obj)
​ long getLong(Object obj)
​ boolean getBoolean(Object ob)
​ double getDouble(Object obj)

private修饰的变量需要设置setAccessible(true)才可以反射设置属性值

​ void setAccessible(true);

* 设置是否取消权限检查
  • true:取消,不检查权限
  • false:不取消,要检查权限,默认值
  • 暴力反射,设置为可以直接访问私有类型的属性。

代码示例

public static void main(String[] args) throws Exception{

        //Class对象是放在方法区(性质跟常量池像的那个,方法区包含常量池)
        Class<Student> studentClass = Student.class;

        Field age = studentClass.getDeclaredField("name");
        Student student = studentClass.getConstructor().newInstance();
        System.out.println("studentBefore = " + student);
        age.setAccessible(true);
        age.set(student,"one");
        System.out.println("studentAfter = " + student);

        Field[] fields = studentClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.getType()==int.class) {
                System.out.println("属性是整型");
            }else if(field.getType()==String.class){
                System.out.println("属性是String类型");
            }
        }
    }

输出结果

studentBefore = Student{id=0, name='null', age=0}

studentAfter = Student{id=0, name='one', age=0}

属性是整型
属性是String类型
属性是整型

Annotation类

类中每一个注解都是Annotation的子类

AnnotatedElement接口,定义了获取注解信息的方法

Class,Constructor,Method,Field等类都实现了AnnotatedElement接口

Annotation接口的方法:

  1. T getAnnotation(Class<T> annotationClass)//根据注解类型获取注解对象那个
  2. Annotation[] getAnnotations()//获取所有注解对象,可以获父类上注解对象,前提标注元注解@Inherited
  3. Annotation[] getDeclaredAnnotations()//获取所有注解对象,仅限本类中的
  4. boolean isAnnotationPresent(Class annotationClass)//判断是否使用了某个注解

获取注解对象的方法:

​ 注解作用在哪个成员上就获得该成员对应的对象获得注解信息

​ 比如:注解作用在类上,那么应该通过Class对象的getAnnotation(Class<T> annotationClass)方法获取

​ 注解作用在方法上,那么应该通过Method对象的getAnnotation(Class<T> annotationClass)方法

​ 构造器和Field同理

相关文章

  • Java基础:反射

    反射注解动态代理相关阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 ...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • java 反射进阶

    1.java反射基础 2.java反射进阶 上一节介绍了反射基础,本节介绍更深入的反射概念。 1.获取不到Clas...

  • Java互联网公司-经典面试题附答案

    基础:Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?优点:反射具有解耦性,缺点:反射属...

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • 反射基础

    反射 反射能在运行时获取任意一个类的所有属性和方法,前提是他能获取到类的Class对象

  • 反射基础

    反射机制提供了运行时访问类内信息的方法,每个类由虚拟机加载到方法区后都会生一个一个对应的class对象,通过这个对...

  • 反射基础

    反射:在程序的运行过程中,能够探测类所拥有的属性和行为的一种能力,把这种机制成为反射. 反射的使用场景: 1>把字...

  • 反射基础

    Class Field(得到属性) SetField(设置属性) Map Method(得到类的方法) Const...

  • 反射基础

    材料准备 Class类 获取Class对象通过类名.class获取通过对象名.getClass()获得通过Clas...

网友评论

      本文标题:反射基础

      本文链接:https://www.haomeiwen.com/subject/baqwqqtx.html