java 反射
1 获取class
- 知道一个类,直接获取 Class 对象
Class class1 = ReflexBean.class;
- 如果已经得到了某个对象,可以通过这个对象获取 Class 对象
ReflexBean bean = new ReflexBean();
Class<?> class3 = bean.getClass(); - 如果你在编译期获取不到目标类型,但是你知道它的完整类路径,那么你可以通过如下的形式来获取 Class 对象
Class<?> class2 = Class.forName("cn.zs.reflex.ReflexBean");
2. 获取构造方法
2.1 获取所有的构造方法
`Constructor[] constructors = class1.getConstructors(); // 获取的构造方法按照在类中定义的顺序`
2.2 获取代参数的构造方法
`Constructor constructor = class1.getConstructor(Integer.class);`
2.3 调用构造方法
`ReflexBean newInstance = (ReflexBean) constructors[0].newInstance(5);`
3. 获取字段
3.1 获取public 字段
`Field[] fields = class1.getFields();
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i].getName()); //获取字段的名称
System.out.println(fields[i].get(bean)); //获取字段的值,bean为该类的实例
}`
3.2 获取所有的字段
`Field[] fields2 = class1.getDeclaredFields();
for (int i = 0; i < fields2.length; i++) {
fields2[i].setAccessible(true); //要设置私有字段的访问权限
System.out.println(fields2[i].getName());
System.out.println(fields2[i].get(bean));
}`
3.3 设置字段的值
4. 获取方法
4.1 获取方法的形式参数
`Method[] methods = class1.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
methods[i].setAccessible(true);
System.out.println(methods[i].getName()); //获取方法的名称
System.out.println(methods[i].getGenericReturnType().toString()); //获取返回值的类型
Class<?>[] parameterTypes = methods[i].getParameterTypes(); // 获取方法形式参数的类型 注意与getTypeParameters()的区别
//Type[] genericParameterTypes = methods[i].getGenericParameterTypes(); 也可以获取方法形式参数的类型
System.out.println(parameterTypes.length);
for (int j = 0; j < parameterTypes.length; j++) {
System.out.println(parameterTypes[j].toString());
}
System.out.println("---------------------");
}`
4.2 获取形式参数的名称
因为在Java中并没有提供相应的API 来获取参数列表名称,因此当有这方面的需求的时候可以使用javassist-3.9.0.GA.jar来获取
要获取的方法为
private Long testMethod3(String str, Integer i) {
return 2L;
}
4.3 执行方法
`class3.getMethod("testMethod2", Integer.class,Double.class).invoke( bean, 1,2.0);`
对应类中的方法是
public void testMethod2(Integer i,Double d) {
System.out.println("执行方法"+ "_"+i+"_"+d);
}
获取的代码为
`public class Test2 {
public static void main(String[] args) throws NotFoundException {
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.get(ReflexBean.class.getName());
CtMethod declaredMethod = ctClass.getDeclaredMethod("testMethod3");
MethodInfo methodInfo = declaredMethod.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attribute = (LocalVariableAttribute) codeAttribute
.getAttribute(LocalVariableAttribute.tag);
//如果执行的是非实例方法(非static方法),局部变量表的第0为索引的Slot默认是传递放方法所属对象实例的引用即this
int pos = Modifier.isStatic(declaredMethod.getModifiers()) ? 0 : 1;
for (int i = 0; i < declaredMethod.getParameterTypes().length; i++) {
System.out.println(attribute.variableName(i+pos));
}
}
}
5. 获取注解
5.1 获取字段的注解
`Field field = class3.getDeclaredField("age");
//field.setAccessible(true);
TestAnnaction1 annotation = field.getAnnotation(TestAnnaction1.class);
System.out.println(annotation.value())`
5.2 批量获得注解
`Field field = class3.getDeclaredField("age");
Annotation[] annotations = field.getAnnotations();
for (int i = 0; i < annotations.length; i++) {
//System.out.println(annotations[i].toString()); //获取注解的类型
System.out.println(annotations[i].annotationType().getCanonicalName()); //获取注解的类型
}`
5.3 获取特定的注解
`TestAnnaction3 annotation = (TestAnnaction3)class1.getAnnotation(TestAnnaction3.class);
System.out.println(annotation.id());
对应的注解类型
@Retention(RetentionPolicy.RUNTIME) //类型虚设置为RUNTIME
@Target(ElementType.TYPE)
public @interface TestAnnaction3 {
int id();
}
6 获取实现的接口和父类
6.1获取父类
` Class superclass = class1.getSuperclass(); //获取父类
System.out.println(superclass.getCanonicalName());`
6.2 获取实现的接口
`Class[] interfaces = class1.getInterfaces(); // 获取实现的接口
for (int j = 0; j < interfaces.length; j++) {
System.out.println(interfaces[j].getCanonicalName());
}`
7 获取泛型
7.1 获取继承类的泛型
`public void get() {
Type genericSuperclass = this.getClass().getGenericSuperclass();
System.out.println("getGenericSuperclass === " + genericSuperclass);
System.out.println(" class 泛型");
if (ParameterizedType.class.isAssignableFrom(genericSuperclass
.getClass())) {
for (Type type : ((ParameterizedType) genericSuperclass)
.getActualTypeArguments()) {
System.out.println(type.toString());
}
}`
7.2 获取接口的泛型
`public class TestInfaceImpl implements TestInterface<Integer> {
public void get() {
Type[] genericInterfaces = this.getClass().getGenericInterfaces();
for (int i = 0; i < genericInterfaces.length; i++) {
Type inter = genericInterfaces[i];
if (ParameterizedType.class.isAssignableFrom(inter
.getClass())) {
for (Type type : ((ParameterizedType) inter)
.getActualTypeArguments()) {
System.out.println(type.toString());
}
}
}
}
}
`
7.3 获取List 和 Map的泛型
`public class TestBeanExtends extends TestBean<String> {
List<String> lists;
Map<String, Integer> maps;
public void getList() throws NoSuchFieldException, SecurityException {
Field declaredField = this.getClass().getDeclaredField("lists");
Type genericType = declaredField.getGenericType();
System.out.println("list 泛型");
if (ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
for (Type type : ((ParameterizedType) genericType)
.getActualTypeArguments()) {
System.out.println(type.toString());
}
}
}
public void getMap() throws NoSuchFieldException, SecurityException {
Field declaredField = this.getClass().getDeclaredField("maps");
Type genericType = declaredField.getGenericType();
System.out.println("map 的泛型");
if (ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
for (Type type : ((ParameterizedType) genericType)
.getActualTypeArguments()) {
System.out.println(type.toString());
}
}
}
`