原文:https://www.jianshu.com/p/5b3acad0f025
什么是反射:
Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。用一句话总结就是反射可以实现在运行时可以知道任意一个类的属性和方法。
优缺点:
上面反射机制的定义还是很言简意赅的。因为反射可以在运行时加载、探知、使用完全未知的类,你只要给我一个路径就可以了,我通过这个路径拿到我需要的东西,我的操作与你无关了,灵活性更高了,类之间的耦合性也就降低了。
同时我们可以获取到类的私有信息,破坏了类的封装,使类变得不安全。使用反射还会降低程序性能。所以说使用反射优点突出,缺点同样突出。
创建一个消费者类:
/**
* Java反射例子
* 消费者类
* @author jinlei
*
*/
public class Consumer {
private long id;//私有的
public String name;//共有的
/*没参数构造体*/
public Consumer() {
}
/*有参数构造体*/
public Consumer(long id, String name) {
this.id = id;
this.name = name;
}
/*getter setter*/
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*私有的无参buy方法*/
@SuppressWarnings("unused")
private static void buy() {
System.out.println("私有的无参buy方法");
}
/*共有的有参有返回值consume方法*/
public String consume(String giftName) {
System.out.println("买了一件礼物: " + giftName);
return giftName;
}
@Override
public String toString() {
return "Consumer [id=" + id + ", name=" + name + "]";
}
}
/**
* 反射测试类
* @author jinlei
*
*/
public class TestReflect {
public static void main(String[] args) throws Exception{
/* 获取对象类型 */
Class<?> clazz = Class.forName("com.jeecms.reflect.Consumer");
Object object = clazz.newInstance();
/* 获取到所有属性 */
Field[] field = clazz.getDeclaredFields();
for (Field f:field) {
//String fieldName = f.getName();// 取到属性名字
//System.out.println(fieldName);
System.out.println(f);
}
/* 获取到所有的方法,包括私有的,但不包括父类的 */
Method[] methods = clazz.getDeclaredMethods();
for (Method m:methods){
//String methodName = m.getName();
//System.out.println(methodName);
System.out.println(m);
}
/* 所有的构造体 */
Constructor[] constructors = clazz.getDeclaredConstructors();
for (Constructor c:constructors){
System.out.println(c);
}
// 调用方法
Method method = clazz.getMethod("consume", String.class);//获取方法
method.invoke(object, "隔壁老王");
//得到属性
Field aField = clazz.getField("name");
//Field aField = clazz.getDeclaredField("name"); //因为id变量是private的,所以不能用getField方法
//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
aField.setAccessible(true);
aField.set(object,"二大爷");
Object obj = aField.get(object);
System.out.println(obj);
// 得到构造器
Constructor constructor = clazz.getDeclaredConstructor(long.class, String.class);
Consumer object2 = (Consumer)constructor.newInstance(2016040221, "王小二");
System.out.println(object2.toString());
}
}
主要的三个方法:
/* 获取到所有属性 */
Field[] field = clazz.getDeclaredFields();
/* 获取到所有的方法,包括私有的,但不包括父类的 */
Method[] methods = clazz.getDeclaredMethods();
获取到方法之后调用Method 的invoke 方法,就能调用了
* 所有的构造体 */
Constructor[] constructors = clazz.getDeclaredConstructors();