java反射的用法

java反射的用法

一、什么是反射机制

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


二、基本用法

// Person.java
public 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: age
06-04 12:16:15.828 12471-12471/? I/System.out: name
06-04 12:16:15.828 12471-12471/? I/System.out: $change
06-04 12:16:15.828 12471-12471/? I/System.out: serialVersionUID

三、应用

// Product.java
public interface Product {
  void show();
}
// ProductA.java
public class ProductA implements Product{
  @Override public void show() {
    System.out.println("this is ProductA");
  }
}
// ProductB.java
public class ProductB implements Product{
  @Override public void show() {
    System.out.println("this is ProductB");
  }
}

// ProductFactory.java
public 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();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chengyuan9160

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值