一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。【这段话摘自百度百科】
java反射有这些功能:
* 在运行时判断一个对象所属的类;
* 在运行时构造任意一个类的对象;
* 在运行时判断任意一个类的成员对象和方法;
* 在运行时调用任意一个类的方法
* 生成动态代理
接下来,将通过一些实例理解java的反射机制。
根据对象获取其完整的包名和类名
abstract class Base{
}
class BaseExt extends Base{
}
public class Reflection {
public static void main(String[] args) {
BaseExt baseExt = new BaseExt();
//通过对象获得其完整的包名和类名
System.out.println("baseExt对象的运行时类的java.lang.Class对象:"+baseExt.getClass());
System.out.println("实例化出对象baseExt的类为:"+baseExt.getClass().getName());
System.out.println("实例化出对象baseExt的类的超类为:"+baseExt.getClass().getSuperclass().getName());
System.out.println("实例化出对象baseExt的类的超类的超类为:"+baseExt.getClass().getSuperclass().getSuperclass().getName());
}
}
运行结果
baseExt对象的运行时类的java.lang.Class对象:class reflection.BaseExt
实例化出对象baseExt的类为:reflection.BaseExt
实例化出对象baseExt的类的超类为:reflection.Base
实例化出对象baseExt的类的超类的超类为:java.lang.Object
1.getClass()的作用是返回该对象的运行时类的java.lang.Class对象;
2.getSuperclass()的作用是返回对象的类的父类的java.lang.Class对象;
3.getName()的作用是根据class获取它的包名和路径;
实例化类的对象,获取类的属性和方法,调用类的方法
class Base1{
public int count;
public void say(String item){
System.out.println("我是Base1类,"+item);
}
public void tell(){
System.out.println("我是不会告诉你我是Base1的");
}
}
class Base2{
public String name;
public void say(String item){
System.out.println("我是Base2类,"+item);
}
public void tell(){
System.out.println("我是不会告诉你我是Base2的");
}
}
class Info{
public void getInfo(Object obj){
//获取obj对象的类名
String className = obj.getClass().getName();
try {
//实例化一个类className的对象
Class<?> base = Class.forName(className);
//获得该类的所有属性
Field[] fields = base.getDeclaredFields();
System.out.println("fields:");
for(Field field:fields){
//访问修饰符
int mo = field.getModifiers();
String modifier = Modifier.toString(mo);
//属性类型
String type = field.getType().getName();
//属性名
String name = field.getName();
System.out.println(" "+modifier + " "+ type + " " +name);
}
//获得该类的所有方法
Method[] methods = base.getMethods();
System.out.println("methods:");
for(Method method:methods){
//访问修饰符
int mmo = method.getModifiers();
String mmodifier = Modifier.toString(mmo);
//返回类型
String mtype = method.getReturnType().getName();
//属性名
String mname = method.getName();
System.out.println(" "+mmodifier + " "+ mtype + " " +mname);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void say(Object obj,String item){
//获取obj对象的类名
String className = obj.getClass().getName();
try{
//实例化一个类className的对象
Class<?> base = Class.forName(className);
//调用base对象所属类的say方法
Method method = base.getMethod("say",String.class);
method.invoke(base.newInstance(),item);
//调用base对象所属类的tell方法
Method method2 = base.getMethod("tell");
method2.invoke(base.newInstance());
}catch(Exception e){
e.printStackTrace();
}
}
}
public class Reflection {
public static void main(String[] args) {
Info info = new Info();
info.getInfo(new Base1());
System.out.println("-------------------------");
info.getInfo(new Base2());
System.out.println("-------------------------");
info.say(new Base1(),"你是谁?");
System.out.println("-------------------------");
info.say(new Base2(),"你是谁?");
}
}
运行结果:
fields:
public int count
methods:
public void say
public void tell
public final void wait
public final void wait
public final native void wait
public boolean equals
public java.lang.String toString
public native int hashCode
public final native java.lang.Class getClass
public final native void notify
public final native void notifyAll
-------------------------
fields:
public java.lang.String name
methods:
public void say
public void tell
public final void wait
public final void wait
public final native void wait
public boolean equals
public java.lang.String toString
public native int hashCode
public final native java.lang.Class getClass
public final native void notify
public final native void notifyAll
-------------------------
我是Base1类,你是谁?
我是不会告诉你我是Base1的
-------------------------
我是Base2类,你是谁?
我是不会告诉你我是Base2的
4.Class<?> base = Class.forName(className) 通过调用Class.forName()实例化一个类的对象;
5.getDeclaredFields()获取该类的属性,getMethods()获取该类的方法,getModifiers获取属性和方法的访问修饰符等;
6.通过Info类中say方法的写法调用类的方法,getMethod方法的第一个参数为方法名,后面是参数类型,无参方法只写方法名即可,invoke方法从第二个参数开始为被调用方法的参数
另外通过阅读java API我们还可以获取到其他的一些方法,比如获取构造方法,获取方法参数等等。
好了,反射暂时先写到这里。