一:反射
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的
类。也就是加载一个运行时才得知名称的class,获得其完整结构。
对于一个java类,可以获取属性、方法、调用它的任意方法。
想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class)
二:Class
//如果已知实例对象class 使用.getClass
//如果已知类 使用.class
//如果未知class 使用Class.forName(class);
获取类对象以及类信息:
使用Class.forName(class)实际是在加载对象,然后返回一个Class对
象,Class.forName()方法实际上也是调用的CLassLoader来实现的,
ClassLoader.getSystemClassLoader().loadClass(“com.test.mytest.ClassForName”);
package test20160814;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
class T {
public int a;
private String b;
public T() {
}
private T(int a, String b) {
this.a = a;
this.b = b;
}
public void haha(String param) {
System.out.println(param);
}
private void xixi(String param) {
System.out.println(param);
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
public class Test extends T {
public int id;
public String name;
private String desc;
public Test() {
}
public Test(int id, String name, String desc) {
this.id = id;
this.name = name;
this.desc = desc;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
private void print(String param) {
System.out.println(param);
}
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
Class clazz = Test.class;
System.out.println("-----------类------------");
System.out.println(Modifier.toString(clazz.getModifiers()));// 类的访问修饰符
System.out.println(clazz.getName() + "_" + clazz.getSimpleName());// 类名:全路径类名_类名
System.out.println("-----------类属性------------");
Field field[] = clazz.getFields();// 返回的是申明为public的属性,包括父类中定义的public
// Field field[] = clazz.getDeclaredFields();//
// 返回的是指定类定义的所有定义的属性,不包括父类的。
for (Field f : field) {
System.out.println(Modifier.toString(f.getModifiers()) + " "
+ f.getType().getSimpleName() + " " + f.getName());// 返回属性全部信息
}
System.out.println("-----------类方法------------");
// Method method[] =
// clazz.getDeclaredMethods();//返回的是申明为public的方法,不包括父类中
Method method[] = clazz.getMethods();// 返回的是指定类定义的所有定义的公共方法,包括父类的。
for (Method m : method) {
m.setAccessible(true);
System.out.println(Modifier.toString(m.getModifiers()) + " "
+ m.getReturnType().getSimpleName() + " " + m.getName());
Class returnType = m.getReturnType();
System.out.println(returnType.getName());// 方法返回值
Class c[] = m.getParameterTypes();// 方法参数
for (Class class1 : c) {
System.out.println("方法参数:" + class1.getSimpleName());
}
}
Method method2 = clazz.getDeclaredMethod("print",new Class[] { String.class });
Test obj = (Test) clazz.newInstance();
method2.invoke(obj, "你大爷");// 执行方法
System.out.println("-----------构造器------------");
Constructor constructor[] = clazz.getDeclaredConstructors();
for (Constructor constructor2 : constructor) {
System.out.println(constructor2.getName());
Class ctype[] = constructor2.getParameterTypes();
for (Class class1 : ctype) {
System.out.println(class1.getName());
}
}
}
}
三:Java反射的作用
1:反射可以解剖类,不使用非正常的操作使用类。
2:反射能提高系统架构的灵活性或者扩展性。
四:Java的坏处
1:使用反射的代码比正常的调用代码多得多。
2:反射操作的效率要比正常操作效率低很多。
3:反射破坏了程序的健壮性,一些非常规的操作会带来很多意想不到的的后果。