java反射的用法

来源:互联网 发布:工业自动化仿真软件 编辑:程序博客网 时间:2024/06/06 14:18

java反射的用法

一、什么是反射机制

简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。


二、基本用法

// Person.javapublic class Person {  private String name;  private int age;  public Person() {  }  public Person(String name, int age) {    this.name = name;    this.age = age;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public int getAge() {    return age;  }  public void setAge(int age) {    this.age = age;  }  public static void sleep() {    System.out.println("go to sleep");  }  private void goShopping() {    System.out.println("go Shopping now");  }}

1.调用普通方法:setAge

Class cls = Class.forName("com.rico.reflectdemo.Person");Method method = cls.getDeclaredMethod("setAge", int.class);Object person = cls.newInstance();method.invoke(person, 20);

这里传int.class,如果传的是Integer.class会报错,提示找不到参数为Integer的方法

06-04 11:56:55.781 6880-6880/com.rico.reflectdemo W/System.err: java.lang.NoSuchMethodException: setAge [class java.lang.Integer]

2.调用私有方法:goShopping

可以调用私有方法吗?

Class cls = Class.forName("com.rico.reflectdemo.Person");Method method = cls.getDeclaredMethod("goShopping");Object person = cls.newInstance();method.invoke(person);

结果报错了

06-04 12:01:06.223 7947-7947/com.rico.reflectdemo W/System.err: java.lang.IllegalAccessException: Class java.lang.Class<com.rico.reflectdemo.MainActivity> cannot access private  method 

难道不能调用私有方法,其实是可以的,需要加上method.setAccessible(true);,加上之后运行下:

06-04 12:02:59.068 8978-8978/com.rico.reflectdemo I/System.out: go Shopping now

3.调用静态方法:goShopping

Class cls = Class.forName("com.rico.reflectdemo.Person");Method method = cls.getDeclaredMethod("sleep");method.invoke(cls);

区别是不需要cls.newInstance(),和静态方法使用习惯保持一致,运行一下

06-04 12:04:18.601 10115-10115/com.rico.reflectdemo I/System.out: go to sleep

4.访问私有属性:age

Class cls = Class.forName("com.rico.reflectdemo.Person");Field field = cls.getDeclaredField("age");Object person = cls.newInstance();field.setAccessible(true);field.set(person, 24);

同样加上field.setAccessible(true);就可以了

5.遍历所有属性

Class cls = Class.forName("com.rico.reflectdemo.Person");Field[] fields = cls.getDeclaredFields();for (Field item:fields) {    System.out.println(item.getName());}

运行结果

06-04 12:16:15.828 12471-12471/? I/System.out: age06-04 12:16:15.828 12471-12471/? I/System.out: name06-04 12:16:15.828 12471-12471/? I/System.out: $change06-04 12:16:15.828 12471-12471/? I/System.out: serialVersionUID

三、应用

// Product.javapublic interface Product {  void show();}// ProductA.javapublic class ProductA implements Product{  @Override public void show() {    System.out.println("this is ProductA");  }}// ProductB.javapublic class ProductB implements Product{  @Override public void show() {    System.out.println("this is ProductB");  }}// ProductFactory.javapublic class ProductFactory {  public static Product produce(int product_index) {    if (product_index == 0) {      return new ProductA();    } else if (product_index == 1){      return new ProductB();    }    return null;  }}

典型的工厂模式,如果要创建ProductC呢?需要修改ProductFactory的代码,太麻烦,怎么样可以一劳永逸?修改下工厂的实现

public class ProductFactory {  public static Product produce(String className) {    try {      return (Product) Class.forName(className).newInstance();    } catch (Exception e) {      e.printStackTrace();    }    return null;  }}

调用一下

Product pro = ProductFactory.produce("com.rico.reflectdemo.ProductA");pro.show();