您的位置:首页 > 编程语言 > Java开发

JAVA学习31_ java反射机制

2016-09-09 15:06 507 查看


java反射机制


java反射机制可以让我们在运行期获取类、接口、变量和方法的信息。通过反射我们可以动态的创建对象,获取类的属性(包括私有属性)、方法等信息;通过反射我们亦可以实现动态代理、动态的类加载以及与泛型相关的操作。


获取类


获取class对象

在获取一个类的相关信息前,我们必须首先获取它的class对象,这里有两种方式:

直接通过Object.class,如下:
Class myClass = MyObject.class;


通过一个类的权限定名
Class myClass = Class.forName("com.xxx.MyObject");



获取类名

获取类名有两种,一种是获取类的全限定名,也就是带有包路径,另一种直接是类名。

获取类的权限定名
Class myClass = MyObject.class;String className = myClass.getName();


获取类名
Class myClass = MyObject.class;String className = myClass.getSimpleName();



获取访问修饰符

通过反射可以获取类的访问修饰符,如public,private或static等

Class class = ....//获取class对象
int modifiers = class.getModifiers();


访问修饰符被包装成int类型,可以通过以下防范判断是哪个类型的修饰符.
Modifier.isAbstract(int modifiers);
Modifier.isFinal(int modifiers);
Modifier.isInterface(int modifiers);
Modifier.isNative(int modifiers);
Modifier.isPrivate(int modifiers);
Modifier.isProtected(int modifiers);
Modifier.isPublic(int modifiers);
Modifier.isStatic(int modifiers);
modifier.isStrict(int modifiers);
Modifier.isSynchronized(int modifiers);
Modifier.isTransient(int modifiers);
Modifier.isVolatile(int modifiers);


获取父类

Class class = ....//获取class对象
Class superClass = class.getSuperClass();
String superName = superClass.getName();
...


获取实现的接口集合

Class class = ....//获取class对象
Class[] interfaces = class.getInterfaces();


获取方法数组

Class class = ...//获取class对象
Method[] methods = class.getMethods();


获取字段集合

Class class = ...//获取class对象
Field[] fields = class.getFields();


获取注解

Class class = ...//获取class对象
Annotation[] annotation = class.getAnnotations();


创建对象

创建对象大体有两种方式:

直接利用class对象的newinstance()方法
Class class = ....//获取class对象
MyObject myObject = (MyObject)class.newInstance();
myobject.setXXX("xxxx");
...


先获取类的构造器,然后通过构造方法去实例化一个对象
Class class = ....//获取class对象
//返回一个构造方法的集合
Construct<?>[] constructs = class.getConstructs();
//这里是调用默认的构造方法来实例化对象
MyObject myObject1 = constructs[0].newInstance();
myObjecy1.setXXX("xxx");
//调用有参构造方法
MyObject myObject2 = constructs[1].newInstance(33,"haha");

//by the way 通过构造方法也可以获取到构造方法的参数信息 如参数名、参数的修饰符,如int、string等
Class[] paramTypes = constructs[1].getParamTypes(); //这是一个参数的对象数组
for(Class parameterType:parameterTypes) {
System.out.println(parameterType.getSimpleName());
//获取修饰符
System.out.println(parameterType.getModifiers());
}



获取变量


获取Field对象

Class class = ....//获取class对象
//获取变量字段的集合
Field[] fields = class.getFields();
for(Field field:fields) {
System.out.println(field.getName());
}
//注意:这种方式只能获取共有变量


获取私有变量

//要想获取私有变量,可以通过下面这个方法
Class class = ....//获取class对象
MyObject myObject = (MyObject)class.newInstance();
Field privateField = myObject.getDeclaredField("私有变量名");
privateField.setAccessible(true); //必须要有这句话,他会关闭指定类Field实例的反射访问检查
System.out.println(privateField.getName());


修改变量

//接着上面的代码
privateField.set(myObject,"ddddd"); //修改刚才获取的变量的内容


获取方法


获取指定的方法

//如果已知方法的名字及参数则可通过下面方式获取该方法
Class  aClass = ...//获取Class对象
//第一个参数为方法名,第二个参数为该方法的参数
Method method = aClass.getMethod("doSomething", new Class[]{String.class});


通过方法对象调用其他方法

Class  aClass = MyObject.class//获取Class对象
Method method = aClass.getMethod("doSomething", new Class[]{String.class});
//第一个参数为一个对象 当主调方法为静态方法时传null即可,若不是则需要传MyObject对象实例
Object returnValue = method.invoke(null,"参数");


获取方法参数及返回类型

Class  class = ...//获取Class对象
Method method = class.getMethod("","");
Class[] paramterTypes = method.getParameterTypes();
//获取返回值
Class returnType = method.getReturnType();


泛型


获取方法泛型的返回类型

class MyClass {
private List<String> list;
public List<String> getStringList() {
return this.list;
}
public void getStringList(List<String> list,Map<String,String> map) {
this.list = list;
}
}

//获取指定的方法
Method method = MyClass.class.getMethod("getStringList",null);
//获取该方法返回的类型对象
Type returnType = method.getGenericReturnType();
System.out.println(returnType+"");
if(returnType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType)returnType;
//该返回类型对象的参数结合
Type[] typeArguments = parameterizedType.getActualTypeArguments();
for(Type typeArgument:typeArguments) {
Class typeArgClass = (Class) typeArgument;
System.out.println("typeArgClass--"+typeArgClass);
}
}
//输出结果:
java.util.List<java.lang.String>
typeArgClass--class java.lang.String


获取方法参数的类型

//与获取返回类型大同小异
Method method2 = MyClass.class.getMethod("getStringList", List.class,Map.class);
Type[] genericParameterTypes = method2.getGenericParameterTypes();
for(Type genericParameterType:genericParameterTypes) {
System.out.println("genericParameterTypes--"+genericParameterType);
if(genericParameterType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
Type[] parameterArgTypes = parameterizedType.getActualTypeArguments();

for(Type parameterArgType:parameterArgTypes) {
System.out.println("parameterArgTypes--"+parameterArgType);
Class typeClass = (Class) parameterArgType;
System.out.println("parameterArgClass--"+typeClass);
}
}
}


数组


通过反射创建一个数组

//创建一个整形数组 第一个参数为类型的class对象、第二个对象为数组大小
int[] intArray = (int[]) Array.newInstance(int.class, 3);


设置数组值

Array.set(intArray, 0, 1);
Array.set(intArray, 1, 2);
Array.set(intArray, 2, 3);


访问数组

System.out.println(Array.get(intArray, 1));
System.out.println(Array.get(intArray, 2));


获取数组的成员类型

String[] strings = new String[3];
Class classl = strings.getClass();
Class type = classl.getComponentType();
System.out.println(type);
//结果
class java.lang.String


参考http://ifeve.com/java-reflection/

原文来自:http://blog.csdn.net/hsk256/article/details/48877535
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: