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)); } } }