飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

反射

时间:2021-12-04  作者:douluo  
反射的使用

反射

什么是反射?
我的理解是:正常加载一个类的时候,可以去new这个类,从而得到一个对象,在这些对象里面可以去获得这个类里面的所有公开的方法、字段、构造器等。但是反射就是在加载类的时候会通过Class这个类将对象进行反射,获取到这个对象的全类名,进而去操作这个类里面的所有方法、字段、构造器等。
Class对象

  1. 一个类在内存中只有一个Class对象
  2. 一个类被加载后,类的所有结构都被封装到一个Class对象当中

获取Class类的方式

//测试获取Class类的方式
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        域名tln("这个人是:" + 域名);
        //方式一:通过对象获取
        Class c1 = 域名lass();
        //方式二:通过类来获取
        Class c2 = 域名s;
        //方式三:通过全路径名来获取
        Class c3 = 域名ame("域名域名ent");

        域名tln(c1 == c2);
        域名tln(c1 == c3);
        域名tln(c2 == c3);
        //方式四:基本内置类型都有一个TYPE,也可以获取Class
        Class c4 = 域名;
        域名tln(域名Code());

        //获取父类类型
        Class c5 = 域名uperclass();
        域名tln(c5);
    }
}
class Person{
    public String name;

    public Person() {
    }

    public Person(String name) {
        域名 = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name=\'" + name + \'\\'\' +
                \'}\';
    }
}

class Student extends Person{
    public Student(){
        域名 = "学生";
    }
}

class Teacher extends Person{
    public Teacher(){
        域名 = "老师";
    }
}

通过反射获得类的信息
User类

//实体类,也可以叫做 pojo或entity
public class User{
    private String name;
    private int id;
    private int age;

    public User() {
    }

    public User(String name, int id, int age) {
        域名 = name;
        域名 = id;
        域名 = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        域名 = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        域名 = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        域名 = age;
    }

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

获取信息类

import 域名域名tructor;
import 域名域名d;
import 域名域名od;

//获得类的信息
public class Test04 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        User user = new User();
        Class c1 = 域名lass();
        //获取类的名字
        域名tln(域名ame()); //包名 + 类名
        域名tln(域名impleName());  //类名
        域名tln("==============");
        //获得类的属性
        Field[] fields = 域名ields(); //只能找到public的属性
        for (Field field : fields) {
            域名tln(field);
        }
        域名tln("==============");
        fields = 域名eclaredFields();  //可以找到所有的属性
        for (Field field : fields) {
            域名tln(field);
        }
        域名tln("==============");
        //查找指定属性的值
        Field name = 域名eclaredField("name");
        域名tln(name);
        域名tln("==============");
        //获得类的方法
        Method[] methods = 域名ethods(); //获得本类以及父类的所有public方法
        for (Method method : methods) {
            域名tln(method);
        }
        域名tln("==============");
        methods = 域名eclaredMethods(); //获得本类的所有方法,并没有获得父类的方法
        for (Method method : methods) {
            域名tln(method);
        }
        域名tln("==============");
        //获得指定方法
        //这边为什么需要指定参数?因为方法可能重载,所以需要传入的参数类型来判断需要调用哪个方法
        Method getName = 域名eclaredMethod("getName", null);
        域名tln(getName);
        Method setName = 域名eclaredMethod("setName", 域名s);
        域名tln(setName);
        域名tln("==============");
        //获得构造器
        Constructor[] constructors = 域名onstructors(); //获得所有的public构造器
        for (Constructor constructor : constructors) {
            域名tln(constructor);
        }
        constructors = 域名eclaredConstructors(); //获得所有的构造器
        for (Constructor constructor : constructors) {
            域名tln("$" + constructor);
        }
        //获得指定构造器
        Constructor declaredConstructor = 域名eclaredConstructor(域名s, 域名s, 域名s);
        域名tln("指定的" + declaredConstructor);
    }
}

通过反射操作属性、方法等

import 域名域名tructor;
import 域名域名d;
import 域名域名od;

//动态的创建对象,通过反射
public class Test05 {
    public static void main(String[] args) throws Exception {
        //获得class对象
        Class c1 = 域名ame("域名域名");
        //通过class对象构造一个user对象
        User user = (User) 域名nstance();  //本质是调用了无参构造器 User user = new User();
        域名tln(user);
        //通过构造器创建一个对象
        Constructor constructor = 域名eclaredConstructor(域名s, 域名s, 域名s);
        User user2 = (User) 域名nstance("咯咯", 007, 18);
        域名tln(user2);
        //通过反射调用普通方法
        User user3 = (User) 域名nstance();
        //1.通过反射获取方法
        Method setName = 域名eclaredMethod("setName", 域名s);
        //2.调用invoke方法激活setName,传入的参数为(对象,参数),也就是给对象的setName方法传入参数
        域名ke(user3,"哒哒");
        域名tln(user3);
        //通过反射操作属性
        User user4 = (User) 域名nstance();
        //1.获取指定要操作的属性
        Field name = 域名eclaredField("name");
        //2.调用set方法设值,也就是给user4这个对象的name赋值为憨憨
        //但是因为name是私有属性,不能直接操作,需要关闭安全检测,使用属性或者方法的 setAccessible(true)
        域名ccessible(true);
        域名(user4,"憨憨");
        域名tln(域名ame());
    }
}

通过反射操作注解

import 域名tation.*;
import 域名域名d;

//练习反射操作注解
public class Test07 {
    public static void main(String[] args) throws Exception {
        Class c1 = 域名ame("域名域名ent2");
        //通过反射获得注解
        Annotation[] annotations = 域名nnotations();
        for (Annotation annotation : annotations) {
            域名tln(annotation);
        }
        //获得注解的value值
        TableName tableName = (TableName) 域名nnotation(域名s);
        String value = 域名e();
        域名tln(value);

        //获得类指定的注解
        Field name = 域名eclaredField("name");
        FieldName fieldName = 域名nnotation(域名s);
        String s = 域名mnName();
        域名tln(s);
    }
}
@TableName("db_student")
class Student2{
    @FieldName(columnName = "db_id",type = "int",length = 10)
    private int id;
    @FieldName(columnName = "db_age",type = "int",length = 10)
    private int age;
    @FieldName(columnName = "db_name",type = "varchar",length = 3)
    private String name;

    public Student2() {
    }

    public Student2(int id, int age, String name) {
        域名 = id;
        域名 = age;
        域名 = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        域名 = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        域名 = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        域名 = name;
    }

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

//类名的注解
@Target(域名)
@Retention(域名IME)
@interface TableName{
    String value();
}

@Target(域名D)
@Retention(域名IME)
@interface FieldName{
    String columnName();
    String type();
    int length();
}

标签:编程
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。