反射的概念
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。
若程序运行时接收到外部传入的一个对象,该对象的编译类型是Object,但程序又需要调用该对象运行类型的方法:
- 若编译和运行类型都知道,使用 instanceof判断后,强转。
- 编译时根本无法预知该对象属于什么类,程序只能依靠运行时信息来发现对象的真实信息,这时就必须使用反射了。
- 要是想得到对象真正的类型,就得使用反射。
Java中,能够调用什么方法,看对象的引用,具体调用什么方法,看引用指向的对象。
反射的优缺点
为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念,
- 静态编译:在编译时确定类型,绑定对象,即通过。
- 动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。
一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发。
它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。
反射获取类
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author zzg
* @date 2021.2.5
*/
public class Reflect {
public static void main(String[] args) throws NoSuchFieldException,ClassNotFoundException,NoSuchMethodException,InstantiationException,IllegalAccessException, InvocationTargetException {
// 这里是正向new一个类,属于静态编译
Phone phone=new Phone();
// phone.setCPU("Intel i5");
// System.out.println(phone.getCPU());
这里是反射获取类
Class cla=Phone.class;
Constructor constructor=cla.getConstructor();//获取类的构造函数
constructor.setAccessible(true);//设置构造方法可访问
Object phone=constructor.newInstance();//动态创造一个类的实例
Method method=cla.getMethod("setCPU", String.class);//获取类的方法
method.invoke(phone,"AMD,yes");//执行方法,需要指定对象
Method get=cla.getMethod("getCPU");
System.out.println(get.invoke(phone));
Field field=cla.getDeclaredField("CPU");
field.setAccessible(true);
field.set(phone,"Intel better");
System.out.println(get.invoke(phone));
// Method set=cla.getMethod("setCPU", String.class);
// Object obj=cla
}
}
class Phone{
private String CPU;
private String Battery;
public Phone(){
}
public void setCPU(String cpu){
this.CPU=cpu;
}
public String getCPU(){
if(CPU==null){
return "还没有设置CPU";
}else{
return this.CPU;
}
}
public void setBattery(String battery){
this.Battery=battery;
}
public String getBattery(){
if(Battery==null){
return "还没有设置battery";
}else{
return this.Battery;
}
}
}