- 概念
java中的重要工具,提供了运行时再根据需要创建对象的功能,提供访问、检测和修改本身状态或行为的能力,也就是说可以修改声明,成员变量,方法和构造方法。 - 作用
1)反编译。编译是将java文件通过javac命令生成.class类文件,反编译就是反过来。
2)通过反射机制访问java对象的属性/字段,方法,构造方法 - java中相关的类
1)java.lang.Class 类
2)java.lang.reflect.Modifier 修饰符
3)java.lang.reflect.Field 成员变量
4)java.lang.reflect.Method 方法
5)java.lang.reflect.Contructor 构造方法 - 实际的使用,见下方代码块(具体方法的使用在注释中有说明)
- 总结
1)Class类常用方法
forName(String ClassFullName)
getName()
getSimpleName()
getModifiers()
getField(String fieldName)
getFields()
getDeclaredFields()
getMethod(methodName,parameter.Class,…)
getMethods()
getDeclaredMethods()
getDeclaredConstruct(parameter.Class…)
getDeclaredConstructs()
getSuperclass()
getInterfaces() Class[]
2)Modifier类常用方法
static toString(mod)
3)Field类常用方法
getModifiers()
getType()
getName()
4)Method类常用方法
getModifiers()
getReturnType()
getName()
getParamterTypes() Class
package com.tests;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import com.classes.*;
/**
* 反射:Java中的工具,运行时再使用。
* 程序可以 访问,检测和修改 本身状态或行为的能力,根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关语义。
* 作用:1.反编译 字节码文件.class->java文件 .java
* 2.通过反射机制访问java对象的 属性/字段,方法,构造方法
* Java中相关的类:
* 1.java.lang.Class 类
* 2.java.lang.reflect.Modifier 修饰符
* 3.java.lang.reflect.Field 成员变量
* 4.java.lang.reflect.Method 方法
* 5.java.lang.reflect.Contructor 构造方法
*
* 下面进入实际的使用方法:
* 1.获得类的相关信息
* 1.1 获得类的类型的三种方式
* 1.1.1 Class c1 = Class.forName("HighStudent");
* 1.1.2 Class c2 = HighStudent.Class;
* 1.1.3 Student hs = new HighStudent(); Class c3 = hs.getClass()
* 1.2 获得目标类名
* 1.2.1 String s1 = c1.getName(); 获得全名(com.classes.HighStudent)
* 1.2.2 String s2 = c1.getSimpleName(); 获得简化的名字(HighStudent)
* 1.3 获得类的修饰词
* Modifier mod = c1.getModifiers();
* String modifiers = Modifier.toString(mod);
*
* 2.获得类类型后,通过类类型实例的newInstance可以创建目标类的实例
* Object o = c1.newInstance();
*
* 3.获得属性/字段/变量
* Field[] fs1 = c1.getFields(); //获得全部获得目标类的所有的公共(public)的字段,包括父类声明的。
* Field[] fs2 = c1.getDeclaredFields(); //获得该类所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段。
* Field f = c1.getDeclaredField("fieldName"); 获得指定名称的属性
* 3.1 Field的方法
* f.getModifiers() 获得字段的修饰词
* f.getType() 获得字段的类型
* f.getName() 获得字段的名称
* 3.2 打破封装
* 通过获得指定的属性,然后通过Field类型对象fn的setAccessible(boolean)方法设置可以通过set(key,value)的方法对key对象设置fn属性为value
* Field fn = c1.getDeclaredField("fieldName");
* Object object = c1.newInstance();
* fn.setAccessible(true);
* fn.set(object,"小明爸爸");
* //此时打印object对象的FatherName属性为“小明爸爸“
* String s = ((HighStudent)object).getFatherName();
* System.out.println(s);
*
* 4.获得方法
* Methods[] methods = c1.getDeclaredMethods() //自己声明的所有方法
* Methods[] methods = c1.getMethods() //获得所有public的方法,包括父类的
* Method method = c1.getMethod(methodName,methodParamterTypes) //获得指定名称和顺序参数列表的方法
* 4.1 Method类型实例方法
* getReturnType() 获取返回值
* getParamterTypes() 获取方法参数列表
*/
public class InfoOfClasses {
public static void main(String[] args){
try {
Class c1 = Class.forName("com.classes.HighStudent");
Class c2 = HighStudent.class;
Student hs = new HighStudent();
Class c3 = hs.getClass();
Object o = c1.newInstance();
int ms = c1.getModifiers();
String modName = Modifier.toString(ms);
/**
* 打印所有属性/成员变量
*/
Field[] fs1 = c1.getFields();
Field[] fs2 = c1.getDeclaredFields();
StringBuilder sb = new StringBuilder();
sb.append(Modifier.toString(c1.getModifiers())+" Class "+c1.getSimpleName()+"(){\n");
for (Field field : fs2) {
sb.append("\t"+Modifier.toString(field.getModifiers())+" "+field.getType().getSimpleName()
+" "+field.getName()+";\n");
}
/**
* 打印所有方法
*/
Method[] methods = c1.getDeclaredMethods();
for (Method method : methods) {
sb.append("\t"+Modifier.toString(method.getModifiers())+" "+
method.getReturnType().getSimpleName()+" "+method.getName()+"(");
Class<?>[] params = method.getParameterTypes();
for (Class<?> class1 : params) {
String paramName = class1.getSimpleName();
sb.append(paramName+",");
}
if(sb.lastIndexOf(",")==(sb.length()-1)){
sb.deleteCharAt(sb.length()-1);
}
sb.append(");\n");
}
/**
* 打印构造方法
* 获取所有构造方法 getDeclaredConstructors();
* 获取指定的构造方法 getDeclaredConstructor(parameterTypes);
* Constructor类型其他方法与方法类型类似
*/
Constructor[] constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
sb.append("\t"+Modifier.toString(constructor.getModifiers())+" "+constructor.getDeclaringClass().getSimpleName()+"(");
Class<?>[] params = constructor.getParameterTypes();
for (Class<?> class1 : params) {
String paramName = class1.getSimpleName();
sb.append(paramName+",");
}
if(sb.lastIndexOf(",")==(sb.length()-1)){
sb.deleteCharAt(sb.length()-1);
}
sb.append(");\n");
}
sb.append("}");
System.out.println(sb);
/**
* 打印目标类的父类和接口
* 获取父类 getSuperclass()
* 获取接口 Class[] infas = c1.getInterfaces()
*/
StringBuilder sb2 = new StringBuilder();
sb2.append(c1.getSimpleName()+"类的父类是"+c1.getSuperclass().getSimpleName()+"\n");
if(c1.getInterfaces().length!=0){
sb2.append(c1.getSimpleName()+"类实现了");
Class[] interfaces = c1.getInterfaces();
for (Class infa : interfaces) {
sb2.append(infa.getSimpleName()+"、");
}
if(sb2.lastIndexOf("、")==(sb2.length()-1)){
sb2.deleteCharAt(sb2.length()-1);
}
sb2.append("接口");
}
System.out.println(sb2);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}