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