目录
反射
概述:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
定义:
RTTI(Run-Time Type Information,通过运行时类型信息)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。
不可避免要对对象类型进行动态判断,也就是动态类型的侦测。
为了更好理解反射这个概念,举个例子:我们现在要写一个类,处理外面传进来的Object对象,但是现在不知道这个对象具体是什么东西,我代码已经编译好了,不能再改,
需要在运行的时候程序去自动判断,并且处理,这就不得已在编写的时候就用到了反射机制,程序自动读取对象的内容。
再举个更现实的例子,java程序读取数据库时,怎么能用一段固定的代码去抽象不同的表?
重要性:
反射很重要,反射式java的高级特性,在各种java框架中都需要使用反射,熟练的使用框架和理解框架,甚至自己开发框架,
都必须掌握java反射机制。
具体操作:
俗话说,类也是个东西,人也是个东西,就像抽象人一样把类也抽象了。
通过反射去硬盘中的Class文件读出,创建Class对象,Class对象仅在需要的时候才会加载,获取对象的class对象引用,
获取Class对象:
在java.lang包中的Class类
在java.lang包中的Object类的.getClass方法获取Class对象
Class c1 = "".getClass();//由对象
Class c2 = String.class;//由类
Class c3 = Class.forName("java.lang.String");//类全名
这三个对象是==的。
//把咱们得到的对象的类名打出来
public void PrintClassName(Object obj){
Class myclass=obj.getClass
System.out.print(myclass.getName());
}
加载:由类加载器完成,找到对应的字节码,创建class对象
链接:验证类中字节码,为静态域分配空间
初始化:如果该类有超类,则对其初始化,执行静态初始化器和静态初始化块
相关的类
Class:类的反射对象;
Field:属性反射对象;
Method:方法反射对象;
Constructor:构造器反射对象;
Class、Field、Method、Construcator:统称为“反射对象”。
既然有上述四类对象,在Class的成员方法就一定存在相应的四类操作
主要方法:
对于Class
String getName()返回类名。
String getSimpleName()返回简单类名,不包含包名,但数组类型使用它比较方便。
Class getSuperClass()获取父类。
static Class<?> forName(String className) 返回给定类名或接口名相关联的Class对象
Class<?>[] getClasses()返回Class对象的数组,此Class对象指定类的内部所有公共类和接口。
Class<?>[] getInterfaces()返回Class对象的数组,此Class对象指定类或接口实现或继承的接口
对于Field
Field[] getDeclaredFields()返回Field对象数组,此Class对象指定类或接口声明的所有字段。
对于Method
Method[] getDeclaredMethods()返回Method对象数组,此Class对象指定类或接口声明的所有方法,但不包括继承的方法。
对于Constructor
Constructor<?>[] getConstructors()返回Constructor对象数组,此Class对象指定类的所有公共构造方法。
注意:get中带有Declared是获取所有的,反之是获取公有的。
除了这四种,还可以拿注解
Annotation[] getAnnotations()返回注解对象的数组
判断方法
boolean isArray():是否为数组类型
boolean isAnnotation():是否为注解类型
boolean isEnum():是否为枚举类型
boolean isInterface():是否为接口类型
boolean isPrimitive():是否为基本类型
使用实例
创建主战坦克类
import java.util.Date;
/**
* Created by zhangshuo on 2018/11/30.
*/
public class Mtank {
String name;
Date madetime;
public String madeplace;
double weight;
public double price;
public static final String TEXT="主战坦克是各种能力均衡的坦克";
public Mtank(String name){
this.name=name;
}
//get/set略
}
创建99坦克类继承主战坦克
/**
* Created by zhangshuo on 2018/11/30.
*/
public class Mtank99A2 extends Mtank{
public Mtank99A2(String name) {
super(name);
}
public class Weapon{
String weaponName;
}
Weapon mainWeapon;
Weapon weaponList[];
public static final String TEXT="99A2主战坦克是中国自主研发的主战坦克";
public void move(){
}
public void attack(){
}
public void antiAircraft(){
}
}
反射实现类
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Created by zhangshuo on 2018/11/30.
*/
public class Reflection {
public void printClassinfo(Class c){//输出类信息
System.out.print("类名:"+c.getName());
System.out.println("父类名:"+c.getSuperclass().getName());
Class[] inClasses=c.getClasses();
for(Class c1:inClasses){
System.out.print("内部类名:"+c1.getName());
}
System.out.println("");
Field[] fields=c.getFields();//获取三种数组
Method[] methods=c.getMethods();
Constructor[] constructors=c.getConstructors();
for(Field fie:fields){
System.out.print("字段名:"+fie.getName());
}
System.out.println("");
for(Method met:methods){
System.out.print("方法名:"+met.getName());
}
System.out.println("");
for(Constructor con:constructors){//输出构造参数类型
System.out.print("构造名:"+con.getName());
Class paramTypes[] = con.getParameterTypes();
for(Class par:paramTypes)
System.out.print(" 传参名:"+par.getName());
System.out.println("");
}
}
}
运行一下
public class Main {
public static void main(String[] args){
Mtank mtank=new Mtank("主战坦克");
Mtank99A2 mtankc=new Mtank99A2("99坦克");
Reflection reflection=new Reflection();
reflection.printClassinfo(mtank.getClass());
System.out.println("-------------------");
reflection.printClassinfo(mtankc.getClass());
}
}