反射的概述
Java反射机制
Java反射是Java语言的一个很重要的特征,它使得Java具有了“动态性”。 Java提供了一套机制来动态获取类的信息以及动态调用对象的方法的功能,这套机制就叫——反射 反射机制是如今很多流行框架的实现基础,其中包括Struts、Spring、Hibernate等。
反射的用途
反射最重要的用途就是开发各种通用框架。
反射的相关类
与Java反射相关的类如下:
- Class类:代表一个类。
- Field类:代表类的成员变量(成员变量也称为类的属性)。
- Method类:代表类的方法。
- modifier类:代表修饰符。
- Constructor类:代表类的构造方法。
- Array类:提供了动态创建数组,以及访问数组的元素的静态方法。
注:在JDK中,主要由以上类来实现Java反射机制,这些类都位于java.lang.reflect包中。
Class类
Class代表一个类,在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。
- 获取Class类的相关方法
asSubclass(Class<U> clazz):把传递的类的对象转换成代表其子类的对象
Cast:把对象转换成代表类或是接口的对象
getClassLoader():获得类的加载器
getClasses():返回一个数组,数组中包含该类中所有公共类和接口类的对象
getDeclaredClasses():返回一个数组,数组中包含该类中所有类和接口类的对象
forName(String className):根据类名返回类的对象
getName():获得类的完整路径名字
newInstance():创建类的实例
getPackage():获得类的包
getSimpleName(:获得类的名字
getSuperclass():获得当前类继承的父类的名字
getInterfaces():获得当前类实现的类或是接口
- 获得类中属性相关的方法
getField(String name):获得某个公有的属性对象
getFields():获得所有公有的属性对象
getDeclaredField(String name):获得某个属性对象
getDeclaredFields():获得所有属性对象
- 获得类中构造器相关的方法
getConstructor(Class...<?> parameterTypes):获得该类中与参数类型匹配的公有构造方法
getConstructors():获得该类的所有公有构造方法
getDeclaredConstructor(Class...<?> parameterTypes):获得该类中与参数类型匹配的构造方法
getDeclaredConstructors():获得该类所有构造方法
- 获得类中方法相关的方法
getMethod(String name, Class...<?> parameterTypes):获得该类某个公有的方法
getMethods():获得该类所有公有的方法
getDeclaredMethod(String name, Class...<?> parameterTypes):获得该类某个方法
getDeclaredMethods():获得该类所有方法
- 获得类中方法相关的方法
getMethod(String name, Class...<?> parameterTypes):获得该类某个公有的方法
getMethods():获得该类所有公有的方法
getDeclaredMethod(String name, Class...<?> parameterTypes):获得该类某个方法
getDeclaredMethods():获得该类所有方法
- 类中其他重要的方法
isAnnotation():如果是注解类型则返回true
isAnnotationPresent(Class<? extends Annotation> annotationClass):如果是指定类型注解类型则返回true
isAnonymousClass():如果是匿名类则返回true isArray() 如果是一个数组类则返回true
isEnum():如果是枚举类则返回true isInstance(Object obj) 如果obj是该类的实例则返回true
isInterface():如果是接口类则返回true
isLocalClass():如果是局部类则返回true
isMemberClass():如果是内部类则返回true
代码示例
- 被反射类Student.java
1 package com.chenmengfan.ekt2_yuxi.demo4; 2 3 public class Student { 4 public String x; 5 protected String y; 6 int z; 7 8 private String name; 9 private int age; 10 11 public String getName() { 12 return name; 13 } 14 15 public void setName(String name) { 16 this.name = name; 17 } 18 19 public int getAge() { 20 return age; 21 } 22 23 public void setAge(int age) { 24 this.age = age; 25 } 26 27 Student(String name, int age) { 28 super(); 29 this.name = name; 30 this.age = age; 31 } 32 33 public void fun1(String a, int b) { 34 System.out.println("a=" + a + ", b=" + b); 35 } 36 37 public String fun2(String a, int b, double c) { 38 return "a=" + a + ",b=" + b + ",c=" + c; 39 } 40 41 @Override 42 public String toString() { 43 return "Student [age=" + age + ", name=" + name + "]"; 44 } 45 46 public Student() { 47 super(); 48 } 49 50 private Student(String name) { 51 super(); 52 this.name = name; 53 } 54 55 protected Student(int age) { 56 super(); 57 this.age = age; 58 } 59 }
- 反射逻辑封装在Demo4.java
1 package com.chenmengfan.ekt2_yuxi.demo4; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Modifier; 6 7 public class Demo4 { 8 public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { 9 Class clz = Student.class; 10 11 Method[] methods = clz.getDeclaredMethods(); 12 for (Method method : methods) { 13 Class[] clzz = method.getParameterTypes(); 14 String temp = ""; 15 for (Class cz : clzz) { 16 temp += cz.getSimpleName()+","; 17 } 18 19 System.out.println(Modifier.toString(method.getModifiers())+"" 20 +method.getReturnType().getSimpleName()+"" 21 +method.getName()+"("+temp+")"); 22 } 23 24 //调用类无参的构造方法实例化对象 25 Student st = (Student)clz.newInstance(); 26 27 //调用无参的构造方法实例化 28 //Student st = (Student)clz.getConstructor().newInstance(); 29 30 //得到fun1方法并调用 31 Method method_fun1 = clz.getMethod("fun1",String.class,int.class); 32 method_fun1.invoke(st,"hello",100); 33 34 Method method_fun2 = clz.getMethod("fun2",String.class,int.class,double.class); 35 Object returnValue = method_fun2.invoke(st,"hello",200,3.14); 36 System.out.println(returnValue); 37 } 38 }
- 控制台输出结果如下:
1 publicStringtoString() 2 publicStringgetName() 3 publicvoidsetName(String,) 4 publicvoidsetAge(int,) 5 publicintgetAge() 6 publicStringfun2(String,int,double,) 7 publicvoidfun1(String,int,) 8 a=hello, b=100 9 a=hello,b=200,c=3.14
总结
技术总结:
Class是一个特殊的类,它的实例用来表示一个.class文件在内存中的存在形势。
反射就是照镜子,照出类的内部结构。利用反射,可以在运行状态下初始化类。
心得总结:
“我在密林中穿行,在瀑布下游泳,我去一切无法到达的地方,无论是地层还是高空。”
“学习的路上是孤独的,需要经过不断坚持,才有变强大的可能。
不过让自己强大起来,这还需要理由吗?”