黑马程序员——高新技术——反射

来源:互联网 发布:h5微信支付 java 编辑:程序博客网 时间:2024/05/21 07:08


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

兴趣是学习编程最好的老师

不积跬步,无以至千里

这辈子没办法做太多事情,所以每一件都要做到精彩绝伦。

<反射>

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

例如:

public class Demo1_Reflect {/** * @param args * @throws ClassNotFoundException  */public static void main(String[] args) throws ClassNotFoundException {Class<?> clazz1 = Class.forName("cn.itcast.bean.Person");Class<?> clazz2 = Person.class;Person p = new Person();Class<?> clazz3 = p.getClass();System.out.println(clazz1 == clazz2);      //trueSystem.out.println(clazz2 == clazz3);      //true}}


public class Demo2_Reflect {/** * @param args *  榨汁机(Juicer)榨汁的案例 * 分别有水果(Fruit)苹果(Apple)香蕉(Banana)桔子(Orange)榨汁(squeeze) * @throws IOException  * @throws Exception  */public static void main(String[] args) throws Exception {BufferedReader br = new BufferedReader(new FileReader("config.txt"));//创建流对象关联config.txtClass<?> clazz = Class.forName(br.readLine());//获取该类的字节码对象Fruit f = (Fruit) clazz.newInstance();//用字节码文件创建对象Juicer j = new Juicer();j.run(f);}}interface Fruit {public void squeeze(); }class Apple implements Fruit {public void squeeze() {System.out.println("榨出一杯苹果汁儿");}}class Orange implements Fruit {public void squeeze() {System.out.println("榨出一杯桔子汁儿");}}class Juicer {public void run(Fruit f) {f.squeeze();}}




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

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

Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数Person p = (Person) con.newInstance("张三",23);//创建对象System.out.println(p);//打印对象}}


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


 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)
public class Demo5_Method {public static void main(String[] args) throws Exception {Class<?> clazz = Class.forName("cn.itcast.bean.Person");Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数Person p = (Person) con.newInstance("张三",23);//创建对象Method m = clazz.getMethod("eat");m.invoke(p);Method m2 = clazz.getMethod("eat", int.class);m2.invoke(p, 10);}}

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


 


0 0
原创粉丝点击