java 反射

一、反射

概念:反射就是:加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)

作用:

  • 得到一个类的全部成分然后操作。
  • 破坏封装性,可以访问私有的对象
  • 绕过范型约束,比如定义了一个String 类型的 ArrayList, 通过反射,可以添加 其它类型的数据。

反射第一步:加载类,获取类的 Class 对象

获取 Class 对象的三种方式

  1. Class c1 = 类名.class
  2. 调用 Class 提供方法:public static Class forName(String package);
  3. Object 提供的方法:public Class getClass();   Class c3 = 对象.getClass();

1. 获取类对象 

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
//        1. Class c1 = 类名.class
        Class c1 = Student.class;
         System.out.println(c1.getSimpleName());        // 输出  类名
        System.out.println(c1);        // 输出 class  包名.类名

//        2. 调用 Class 提供方法:public static Class forName(String package);
        Class c2 = Class.forName("reflect.Student");
        System.out.println(c2);      //输出  class  包名.类名

//        3. Object 提供的方法:public Class getClass();
        Student student = new Student();
        Class c3 = student.getClass();
        System.out.println(c2);      //输出  class  包名.类名
    }
}

2.  获取构造器

public class Demo2 {
    public static void main(String[] args) throws NoSuchMethodException {
      
        // 获取构造器信息并进行操作
          // 获取多个构造器
        Constructor[] cons = c1.getDeclaredConstructors();
        for (Constructor con : cons) {
            // reflect.Student(0) 无参 、 reflect.Student(2) 2个参数构造
            System.out.println(con.getName() + "(" + con.getParameterCount() + ")");
        }

        // 获取单个构造器
        Constructor con1 = c1.getDeclaredConstructor();// 无参构造
        System.out.println(con1.getName() + "(" + con1.getParameterCount() + ")");   // reflect.Student(0)
    }

 // 指定获取单个有参构造器(Integer 类型和 String 类型的构造器)
        Constructor con1 = c1.getDeclaredConstructor(Integer.class, String.class);// 有参构造
        System.out.println(con1.getName() + "(" + con1.getParameterCount() + ")");   // reflect.Student(2)
}

3. 获取成员变量

public class Demo2 {
    public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
        // 反射类第一步:获取类的信息
        Class c1 = Student.class;

        Field field = c1.getDeclaredField("name");   // name 是成员变量名称
        Field field1 = c1.getDeclaredField("age");   // aeg 是成员变量名称
        System.out.println(field.getName() + "(" + field.getType().getName() + ")");   // name(java.lang.String)
        System.out.println(field1.getName() + "(" + field1.getType().getName() + ")");  // age(java.lang.Integer)


//获取成员变量目的还是取值和赋值
        Field ageField = c1.getDeclaredField("age");
        Student stu = new Student("张安");
        ageField.setAccessible(true);  // 私有属性不能直接访问,需要绕过访问权限直接访问
        ageField.set(stu, 19);
        System.out.println(stu);  // Student{age=19, name='张安'}

       Integer age = (Integer) ageField.get(stu);   // 等价于 stu.getAge()
        System.out.println(age);  // 19

  }
}

4 获取方法

public class Demo2 {
    public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException {
        // 反射类第一步:获取类的信息
        Class c1 = Student.class;

        // 获取单个成员变量方法
        Method m0 = c1.getDeclaredMethod("eat");   // 获取无参参方法
        Method m1 = c1.getDeclaredMethod("eat", String.class);   // 获取有参方法
        System.out.println(m0.getName() + "(" + m0.getParameterCount() + ")");   // eat(0)
        System.out.println(m1.getName() + "(" + m1.getParameterCount() + ")");  // eat(1)

        Student s1 = new Student(20, "小红");
        m0.setAccessible(true);  // 绕过访问权限,直接访问
        Object res1 = m0.invoke(s1);// 唤醒对象的 eat 无参 方法,相当于 student.eat();
        System.out.println(res1);

        Object res2 = m1.invoke(s1, "皮蛋");   // 有参方法
        System.out.println(res2);
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值