public class ClassTest {
private volatile int i;
public String s;
protected char c;
static int[] ints = {1,2,3};
private ClassTest(){
}
public ClassTest(int i){
this.i = i;
}
private class InnerClass{}
/*反射:Java作为动态语言的核心
* 虽然使用反射会降低程序性能,但他使程序有了更好的灵活性*/
@Test
static void test() throws IllegalAccessException, InstantiationException {
/*Class:表示一个类或接口的运行时的状态(基本数据类型也可以有对应的Class)
在包java.lang.reflect中提供了一些相关结构
如Field,Method,Constructor等,在他们的根接口AnnotatedElement
中声明了一些操作类中结构的规范
* 没有公共的构造器
* 唯一的构造器被JVM使用
* 获得一个Class实例的三种方式
* 1.通过class关键字*/
Class<ClassTest> ctClass = ClassTest.class;
/*2.通过实例调用getClass()方法
* 适用于未知类型的实例*/
ClassTest c = new ClassTest();
Class ctClass1 = c.getClass();
/*3.通过全限定名称(内部类名称为:所在类全限定名称$内部类名称)
如:Class c = Class.forName("com.snake.ClassTest$innerClass")
* 如果未在当前工程下找到相关结构则会抛出异常
* Spring读取配置文件加载对象就是使用的这种方式*/
Class ctClass2 = null;
try {
ctClass2 = Class.forName("com.snake.ClassTest");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
/*一些Class中的方法*/
/*获取此基础类的父类的运行时类,如果此Class是Object或接口的运行时类则返回null*/
Class superclass = ctClass.getSuperclass();
/*如果此基础类是一个注解类则返回true*/
ctClass.isAnnotation();
/*获取此基础类实现的所有接口的运行时类*/
Class[] interfaces = ctClass.getInterfaces();
/*判断此基础类是否有被指定类型的注解所修饰*/
ctClass.isAnnotationPresent(FunctionalInterface.class);
/*当此基础类是一个匿名类时返回true*/
ctClass.isAnonymousClass();
/*当此基础类是一个数组时返回true*/
ctClass.isArray();
/*判断此基础类是否为指定Class参数的父结构或二者是否是同一类的运行时类*/
boolean from = ctClass1.isAssignableFrom(ctClass);
/*当此基础类是一个枚举类时返回true*/
ctClass.isEnum();
/*当指定的引用类型实例强转为此基础类而不引发类型不匹配异常时返回true,此方法等效与instanceof关键字*/
Object classTest = new ClassTest();
ctClass.isInstance(classTest);
/*当此基础类是一个接口时返回true*/
ctClass.isInterface();
/*当基础类是一个局部内部类时返回true*/
ctClass.isLocalClass();
/*当基础类是一个成员内部类时返回true*/
ctClass.isMemberClass();
/*当此基础类是基本数据类型即8种基本数据类型和void时返回true*/
boolean isPrimitive = void.class.isPrimitive();
/*返回此基础类的实例,相当于调用其默认的无参构造器,若该类没有该构造器
* 或者访问权限不足时均会抛出异常*/
ClassTest classTes = ctClass.newInstance();
/*将此基础类强转为指定类型,如果转换成功则返回转换后的运行时类,失败抛出异常*/
ctClass.asSubclass(Object.class);
/*将指定类型实例强转为此基础类,成功则返回此基础类实例,失败抛出异常*/
Object s = "ss";
String ss = String.class.cast(s);
/*获取此基础类类名*/
String name = ctClass.getSimpleName();
/*获取此基础类的全限定名称*/
String name1 = ctClass.getName();
/*返回Java语言规范的类名称,若此基础类是匿名类,局部类或数组则返回null*/
String name2 = ctClass.getCanonicalName();
/*返回此基础类所有的公共成员内部类*/
Class<?>[] classes = ctClass.getClasses();
/*返回此基础类所有的成员内部类*/
Class<?>[] classes1 = ctClass.getDeclaredClasses();
/*返回数组组件的运行时类,若此基础类不是数组则返回null*/
Class componentType = String[].class.getComponentType();
/*获得此基础类的类加载器*/
ClassLoader cl = ctClass.getClassLoader();
/*通过运行时类获得一个相应的基础类实例*/
try {
/*通过getConstructor获取一个Class中的构造器,其中参数列表为构造器参数对应的运行时类
* 如果该构造器不是public或不存在对应的参数列表则会抛出异常*/
Constructor<ClassTest> constructor = ctClass2.getConstructor(int.class);
/*使用newInstance()来获得一个实例,参数为传递到该构造器的实际的值
该方法返回值取决于Constructor的泛型*/
ClassTest classTest1 = constructor.newInstance(10);
/*对于非public的构造器只需要加个Declared就可以搞定,同样适用用于属性和方法*/
Constructor constructor1 = ctClass1.getDeclaredConstructor();
/*设置强制访问private或权限不足的结构*/
constructor1.setAccessible(true);
/*获取实例(破解单例模式的必备利器)
* 当此构造器是枚举类时调用newInstance会引发异常*/
Object o = constructor1.newInstance();
/*内部类的实例获取*/
Class innerClass = InnerClass.class;
/*内部类构造器的获取需要所在类的运行时类作为参数*/
Constructor constructor2 = innerClass.getDeclaredConstructor(ClassTest.class);
constructor2.setAccessible(true);
/*获取内部类实例需要所在类的实例*/
Object o1 = constructor2.newInstance(o);
/*获取此Class中所有的公共构造器*/
Constructor[] cs = ctClass2.getConstructors();
/*获取此Class中所有的构造器*/
Constructor[] cs1 = ctClass2.getDeclaredConstructors();
/*获取指定名称的属性,若此属性不存在则会抛出异常*/
Field field = ctClass2.getDeclaredField("i");
field.setAccessible(true);
/*获取指定实例中此属性的值*/
Object val = field.get(o);
/*设置指定实例中此属性的值,如果要设置的值类型与属性实际参数不匹配则会抛出异常*/
field.set(o,10);
/*获取此Class中所有的公共属性*/
Field[] fields = ctClass2.getFields();
/*获取此Class中所有的属性*/
Field[] fields1 = ctClass2.getDeclaredFields();
/*获得此属性类型的运行时类*/
Class type1 = field.getType();
/*如果此属性是枚举类型元素则返回true*/
field.isEnumConstant();
/*若此属性是有JVM动引入的则返回true*/
field.isSynthetic();
/*获取指定名称和其参数列表的方法,若此方法不存在则会抛出异常
* 获取和执行类似于构造器
* 可变形参实际上是一个数组*/
Method method = ctClass2.getDeclaredMethod("setI",int.class,int[].class);
method.setAccessible(true);
/*执行指定实例的此方法(如果此方法是静态的则不必要指定实例(可以传递一个null),同样适用于属性
因为静态结构存在与静态域中,而不属于实例),
如果返回值为void则invoke()会返回null*/
Object val1 = method.invoke(o,100,null);
/*获取此Class中所有的公共方法*/
Method[] methods = ctClass2.getMethods();
/*获取此Class中所有的方法*/
Method[] methods1 = ctClass2.getDeclaredMethods();
/*获取此方法中所有的参数*/
Parameter[] parameters = method.getParameters();
/*获取此方法中所有参数的运行时类*/
Class[] parameterTypes = method.getParameterTypes();
/*获取此方法抛出的所有异常的运行时类*/
Class[] exceptions = method.getExceptionTypes();
/*获取此方法返回值类型*/
Class type = method.getReturnType();
/*获取此方法的形参数量*/
int count = method.getParameterCount();
/*若此方法的参数列表中含有可变形参则返回true*/
method.isVarArgs();
/*若此方法是桥接方法(即继承父类中泛型方法,重写时明确指定了泛型类型的方法)则返回一个true*/
method.isBridge();
/*若此方法是一个默认实现方法则返回true*/
method.isDefault();
/*若此方法是由JVM引入则返回true(即当一个内部类所有的属性和方法均为private时,为了在外部类访问
这些结构而动态生成的方法)*/
method.isSynthetic();
/*一些对类,属性,方法通用的操作方法*/
/*返回修饰结构的所有注解*/
field.getAnnotations();
/*返回修饰此结构的所有注解,会忽略来自继承于父结构的注解*/
method.getDeclaredAnnotations();
/*获取修饰此结构指定类型的注解*/
Override override = method.getAnnotation(Override.class);
/*获取此结构名称*/
method.getName();
/*获取此结构修饰符的数字表示形式
* 由Modifier进行解码*/
int i = field.getModifiers();
Modifier mod = new Modifier();
System.out.println(mod.toString(i));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "ClassTest{" +
"i=" + i +
", s='" + s + '\'' +
", c=" + c +
'}';
}
public void setI(int i,int ... is) {
this.i = i;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public char getC() {
return c;
}
public void setC(char c) {
this.c = c;
}
public static int[] getInts() {
return ints;
}
public static void setInts(int[] ints) {
ClassTest.ints = ints;
}
public int getI() {
return i;
}
}