-
反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。
-
简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。
程序中一般的对象的类型都是在编译期就确定下来的,而Java反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。
反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
Java反射框架主要提供以下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
- 在运行时调用任意一个对象的方法
//反射
static void refaletion() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//获取对象
Class clazz = int.class;
//判断对象实例类型
clazz.isInstance(Integer.class);
Class str = String.class;
//创建实例
str.newInstance();
//反射调用
Class c = MainTest.class;
Object obj = c.newInstance();
//反射方法 第一个参数方法名字,第二参数是参数类型
Method method = c.getMethod("add", int.class);
//反射全部方法
Method[] methods = c.getMethods();
System.out.println("****开始反射getMethods****");
for (Method m : methods
) {
System.out.println(m);
}
//反射私有方法
// c.getDeclaredMethod("add3", int.class);
//反射全部私有方法
Method[] methods2 = c.getDeclaredMethods();
System.out.println("****开始反射getDeclaredMethods****");
for (Method m : methods2
) {
System.out.println(m);
}
System.out.println("****开始反射getFields****");
//反射字段
Field[] fields = c.getFields();
for (Field f : fields
) {
System.out.println(f);
}
//调用方法
method.invoke(obj, 20);
JavaTest javaTest = new JavaTest();
Class<? extends JavaTest> aClass = javaTest.getClass();
Method[] methods1 = aClass.getMethods();
for (Method m : methods1
) {
try {
if (m.isAnnotationPresent(Test.class)) {
m.setAccessible(true);
m.invoke(javaTest, null);
}
}catch (Exception e){
System.out.println("反射测试错误");
}
}
}
getMethods
获取自身的public方法和父类的public方法
public int MainClass2$MainTest.add(int)
public int MainClass2$MainTest.add2(int)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
getDeclaredMethods
获取类自身全部的方法,不包括父类的。
public int MainClass2$MainTest.add(int)
public int MainClass2$MainTest.add2(int)
private int MainClass2$MainTest.add3()
getFields
获取自身类的public修饰的字段
public final int MainClass2$MainTest.finA
public int MainClass2$MainTest.pubA
栗子二
@Test(name = "zj")
public class JavaTest {
@Test(name = "zj age")
private int age = 10;
@Test(name = "zj1")
public void add1() {
System.out.println("add1 " + 1 + 1);
}
@Test(name = "zj2")
private void add2() {
System.out.println("add2 " + 1 + 1);
}
@Test(name = "zj2")
public void add3() {
System.out.println("add3 " + 1 / 0);
}
}
//获取字段注解
Field age1 = JavaTest.class.getDeclaredField("age");
Test annotation = age1.getAnnotation(Test.class);
System.out.println(annotation.name());
//获取方法中的注解
Method add1 = JavaTest.class.getDeclaredMethod("add1");
Test annotation1 = add1.getAnnotation(Test.class);
Annotation[] annotations = add1.getAnnotations();
for (Annotation a : annotations) {
System.out.println("--方法注解--");
System.out.println(a.annotationType().getSimpleName());
}
//如果想访问private修饰的字段需要设置 Accessible属性。
Field age = JavaTest.class.getDeclaredField("age");
age.setAccessible(true);
JavaTest javaTest1 = new JavaTest();
System.out.println("--获取私有字段值--");
System.out.println(age.get(javaTest1));
网友评论