JAVA反射

什么是反射

定义:反射是一种机制,利用反射机制动态的实例化对象、读写属性、调用方法、构造函数。

反射的优点:增加程序的灵活性
反射的缺点:1性能第一 2安全限制 3内部暴露

如何获取对象(3种)

1,Class.forName("类的全路径名");      jdbc、自定义MVC框架要用

2,类名.class      做通用的查询

3,类实例.getClass()    做通用的增删改

下面看下我们需要用到得Student类

 1 2 
 3 public class Student {
 4     private String sid;
 5 
 6     private String sname;
 7 
 8     public Integer age;
 9     
10     static{
11         System.out.println("加载进jvm中!");
12     }
13 
14     public Student() {
15         super();
16         System.out.println("调用无参构造方法创建了一个学生对象");
17     }
18 
19     public Student(String sid) {
20         super();
21         this.sid = sid;
22         System.out.println("调用带一个参数的构造方法创建了一个学生对象");
23     }
24 
25     public Student(String sid, String sname) {
26         super();
27         this.sid = sid;
28         this.sname = sname;
29         System.out.println("调用带二个参数的构造方法创建了一个学生对象");
30     }
31 
32     @SuppressWarnings("unused")
33     private Student(Integer age) {
34         System.out.println("调用Student类私有的构造方法创建一个学生对象");
35         this.age = age;
36     }
37 
38     public String getSid() {
39         return sid;
40     }
41 
42     public void setSid(String sid) {
43         this.sid = sid;
44     }
45 
46     public String getSname() {
47         return sname;
48     }
49 
50     public void setSname(String sname) {
51         this.sname = sname;
52     }
53 
54     public void hello() {
55         System.out.println("你好!我是" + this.sname);
56     }
57 
58     public void hello(String name) {
59         System.out.println(name + "你好!我是" + this.sname);
60     }
61 
62     @SuppressWarnings("unused")
63     private Integer add(Integer a, Integer b) {
64         return new Integer(a.intValue() + b.intValue());
65     }
66 
67     @Override
68     public String toString() {
69         return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";
70     }
71     
72 }

第一种Class.forName("类的全路径名"); 

Class<?> clz=Class.forName("com.zking.reflect.Student");
System.out.println(clz);

第二种类名.class

Class<?> clz=Student.class;
System.out.println(clz);

第三种类实例.getClass()

Student stu=new Student();
Class<?> clz=stu.getClass();
System.out.println(clz);

反射实例化

一,
//
反射调用无参构造方法创建了一个学生对象 Student stu=(Student) clz.newInstance(); // 要拿到构造类 Constructor con = clz.getConstructor(String.class); // 通过构造器实例化对象 Student stu = (Student) con.newInstance("s001"); 二, //调用带二个参数的构造方法创建了一个学生对象 Constructor con = clz.getConstructor(String.class,String.class); //通过构造器实例化对象 Student stu = (Student) con.newInstance("s001","zs"); 三, /(getConstructor只能寻找到public修饰得构造器,getDeclaredConstructor可以寻找到任何修饰符修饰得构造器) Constructor con = clz.getConstructor(Integer.class); Constructor con = clz.getDeclaredConstructor(Integer.class); con.setAccessible(true); //通过构造器实例化对象 Student stu = (Student) con.newInstance(12);

动态调用方法(要先设置方法的访问权限setAccessible(true),不然访问不了)

public class Demo3 {

    public static void main(String[] args) throws Exception{
        Student stu=new Student();
//        stu.hello();
        Class clz=stu.getClass();
//        Method m= clz.getDeclaredMethod("hello");
//        m.invoke(stu);
        
//        Method m= clz.getDeclaredMethod("hello",String.class);
//        m.invoke(stu,"zs");
        
        Method m=clz.getDeclaredMethod("add",Integer.class,Integer.class);
        m.setAccessible(true);
        //invoke:如何反射动态调用得方法是被void所修饰,那么返回得就是NULL
        //如果反射动态调用得方法是不被void所修饰,那么返回得就是被调用得方法得返回值
        Object invoke=m.invoke(stu,20,5);
        System.out.println(invoke);
        
        
    }
    
}

读写属性

public class Demo4 {

    public static void main(String[] args) throws Exception{
        Student stu=new Student("s002","ls");
//        stu.setSid("s001");
        stu.age=22;
//        System.out.println(stu);
        
        
        
        Class clz=stu.getClass();
//        Field field= clz.getDeclaredField("sid");
//        field.setAccessible(true);
//        field.set(stu,"s002");
//        System.out.println(stu);
//        field.get(stu);
//        System.out.println(stu);
//        System.out.println(field.get(stu));
        
        Field[] fields= clz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.getName()+":"+field.get(stu));
        }
    }
}
原文地址:https://www.cnblogs.com/ztbk/p/11024852.html