Java反射的个人理解:反射就是一种 了解类并使用类 的一套方法;
学过Java基础的都知道如何进行类的实例化,也知道通过实例调用变量或者方法;
但很多时候类不是我们自己写的,所以我们对类不是很了解,这个时候可以通过反射来了解或者调用类本身。
假设有个类 名字是A
Class A{
}
了解这个类我们可以用它创建变量,调用函数,但是当你不知道这个类,那么关于函数本身是不是无从下手,怎么办?
一切类是Class类的对象;Class c1=A.class所以我们的到的是一个等同于类本身的东西,如c1,官方名叫类类型(Class Type),通过c1可以对类A进行一系列操作;
深入了解,有人把类类型叫做字节码文件 很贴切;
因为反射只存在于在运行阶段,也就是在运行时,调用已经编译好的Class,比如Class c=A.class,可以理解为调用A已经编译好的类文件 A.class,所以与反射相关的所有参数都得是类类型,对应各个编译好的文件,比如利用反射调用注解 都得是XX.class,而且注解的生存周期必须是Runtime,这样运行时这些注解还存在
0.三种反射初始化
Class c1=A.class;
A a=new A();
Class c2=a.getClass();
try {
Class c3=Class.forName("A");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
1. 创建实例;
通过
A a2=(A)c1.newInstance();
创建了A的实例a2,是不是通过类类型c1实现了和类A一样的实例化功能
那么我们得到了A类的替身c1,从而可以对类本身进行一系列操作,如类里面的函数,函数的返回值和参数值;
2. 方法
如下,A类中定义了3个函数,通过c1.getMethod我们得到了一类A中的
方法集合(Method[] methods);
方法返回值类类型(Class reType);
方法函数值类类型(Class[] paraTypes);
从而可以进一步调用函数
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by XUH-h on 2017/7/19.
*/
public class SimpleTest {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
Class c1=A.class;
try {
Method m1=c1.getMethod("print", int.class, int.class);
Method m2=c1.getMethod("print", new Class[]{String.class,String.class});
m1.invoke(new A(),1,2);
Method[] methods=c1.getDeclaredMethods(); //函数类类型数组
for (Method method : methods
) {
System.out.println("METHOD: "+method.getName());
Class reType = method.getReturnType();//函数返回值类类型
System.out.println(" RETURN: "+reType.getName());
Class[] paraTypes = method.getParameterTypes();//函数参数类类型数组
for (Class paraType : paraTypes
) {
System.out.println(" PARAMETER: "+paraType.getName());
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
class A{
public void print(int a,int b){
System.out.println(a+b);
}
public void print(String a,String b){
System.out.println(a.toUpperCase()+" "+b.toLowerCase());
}
public String print2(int a,int b){
return ""+a*b;
}
}
运行结果,得到了A类中所有函数的返回值类型和参数类型,也可以调用A中的函数;
3
METHOD: print
RETURN: void
PARAMETER: java.lang.String
PARAMETER: java.lang.String
METHOD: print
RETURN: void
PARAMETER: int
PARAMETER: int
METHOD: print2
RETURN: java.lang.String
PARAMETER: int
PARAMETER: int
因此我们看到,当你不了解类,或者不需要了解,只是调用的时候可以使用反射轻松达到;因而
类类型就是可以进行各种操作的类本身
另外一个作用是实现动态加载,
比如
Class.forName(args[0])
可以在编译后,运行时动态加载所需要的类
还比如jdbc与MySQL连接,
Class.forName("driver")
就使用了反射