码迷,mamicode.com
首页 > 其他好文 > 详细

黑马程序员__反射

时间:2015-05-13 19:57:33      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

<反射>

1.Class
  .class文件加载到内存中就是一个Class对象
  获取Class对象的方式有3种:
      Class.forName();
      类名.class
      对象.getClass()

例如:

[java] view plaincopy
  1. public class Demo1_Reflect {  
  2.   
  3.     /** 
  4.      * @param args 
  5.      * @throws ClassNotFoundException  
  6.      */  
  7.     public static void main(String[] args) throws ClassNotFoundException {  
  8.         Class<?> clazz1 = Class.forName("cn.itcast.bean.Person");  
  9.         Class<?> clazz2 = Person.class;  
  10.           
  11.         Person p = new Person();  
  12.         Class<?> clazz3 = p.getClass();  
  13.           
  14.         System.out.println(clazz1 == clazz2);      //true  
  15.         System.out.println(clazz2 == clazz3);      //true  
  16.     }  
  17.   
  18. }  


[java] view plaincopy
  1. public class Demo2_Reflect {  
  2.   
  3.     /** 
  4.      * @param args 
  5.      *  榨汁机(Juicer)榨汁的案例 
  6.      * 分别有水果(Fruit)苹果(Apple)香蕉(Banana)桔子(Orange)榨汁(squeeze) 
  7.      * @throws IOException  
  8.      * @throws Exception  
  9.      */  
  10.     public static void main(String[] args) throws Exception {  
  11.         BufferedReader br = new BufferedReader(new FileReader("config.txt"));//创建流对象关联config.txt  
  12.         Class<?> clazz = Class.forName(br.readLine());            //获取该类的字节码对象  
  13.         Fruit f = (Fruit) clazz.newInstance();              //用字节码文件创建对象  
  14.         Juicer j = new Juicer();  
  15.         j.run(f);  
  16.     }  
  17.   
  18. }  
  19. interface Fruit {  
  20.     public void squeeze();   
  21. }  
  22.   
  23. class Apple implements Fruit {  
  24.     public void squeeze() {  
  25.         System.out.println("榨出一杯苹果汁儿");  
  26.     }  
  27. }  
  28.   
  29. class Orange implements Fruit {  
  30.     public void squeeze() {  
  31.         System.out.println("榨出一杯桔子汁儿");  
  32.     }  
  33. }  
  34.   
  35. class Juicer {  
  36.     public void run(Fruit f) {  
  37.         f.squeeze();  
  38.     }  
  39. }  




 2.Constructor
     Class类的newInstance()方法是使用该类无参的构造函数创建对象
     调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数,然后再调用Constructor类的newInstance("张三",20)方法创建对象

[java] view plaincopy
  1. public class Demo3_Constructor {  
  2.     public static void main(String[] args) throws Exception {  
  3.         Class<?> clazz = Class.forName("cn.itcast.bean.Person");  
  4.         Person p = (Person) clazz.newInstance();                     //使用无参的构造函数创建对象  
  5.         System.out.println(p);                                       

[java] view plaincopy
  1.         Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数  
  2.         Person p = (Person) con.newInstance("张三",23);           //创建对象  
  3.         System.out.println(p);                      //打印对象  
  4.     }  
  5.   
  6. }  


 3.Field
     Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以用getDeclaedField("name")方法获取
     通过set(obj, "李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限
     用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值
[java] view plaincopy
  1. public class Demo4_Field {  
  2.     public static void main(String[] args) throws Exception {  
  3.         Class<?> clazz = Class.forName("cn.itcast.bean.Person");  
  4.         Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数  
  5.         Person p = (Person) con.newInstance("张三",23);           //创建对象  
  6.           
  7.         /*Field f = clazz.getField("name"); 
  8.         System.out.println(f);*/  
  9.         Field f = clazz.getDeclaredField("name");           //暴力反射  
  10.         f.setAccessible(true);                      //去除权限  
  11.         f.set(p, "李四");  
  12.         System.out.println(p);  
  13.     }  
  14.   
  15. }  


 4.Method
     Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法
     调用invoke(Object, Object...)可以调用该方法
     Class.getMethod("eat") invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)
[java] view plaincopy
  1. public class Demo5_Method {  
  2.     public static void main(String[] args) throws Exception {  
  3.         Class<?> clazz = Class.forName("cn.itcast.bean.Person");  
  4.         Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数  
  5.         Person p = (Person) con.newInstance("张三",23);       //创建对象  
  6.           
  7.         Method m = clazz.getMethod("eat");  
  8.         m.invoke(p);  
  9.           
  10.         Method m2 = clazz.getMethod("eat"int.class);  
  11.         m2.invoke(p, 10);  
  12.     }  
  13.   
  14. }  

5.泛型反射
  创建一个集合对象,泛型为String类型,需要向这个集合中添加Integer对象
  泛型在编译时存在,运行时会被擦除
[java] view plaincopy
  1. public class Test3 {  
  2.   
  3.     public static void main(String[] args) throws Exception {  
  4.         ArrayList<String> list = new ArrayList<>();  
  5.         list.add("黑");  
  6.         list.add("马");  
  7.         list.add("程");  
  8.         list.add("员");  
  9.           
  10.         Class<?> clazz = Class.forName("java.util.ArrayList");        //获取字节码文件  
  11.         Method m = clazz.getMethod("add", Object.class);        //获取方法  
  12.         m.invoke(list, 521);                        //执行方法  
  13.         m.invoke(list, true);  
  14.         System.out.println(list);  
  15.           
  16.     }  
  17.   
  18. }  

黑马程序员__反射

标签:

原文地址:http://blog.csdn.net/haojude/article/details/45694821

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!