动态语言定义:
• 反射机制
– 指的是可以于运行时加载、探知、使用编译期间完全未知的类。
– 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个 已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对 象,都能够调用它的任意一个方法和属性;
Class c = Class. f o r N a m e (“com.lsd.test.User”);
– 加载完类之后,在堆内存中,就产生了一个 Class 类型的对象(一个 类只有一个 Class 对象),这个对象就包含了完整的类的结构信息。 我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过 这个镜子看到类的结构,所以,我们形象的称之为:反射
反射示例:
/**
* 运用反射api获取类的信息
*/
public class Demo2 {
public static void main(String[] args) {
String path="reflect.User";
try{
//一个类被加载后,jvm会创建一个对应该类的Class对象,该累的所有组织结构都会方法哦Class中
//类似一个镜子,可以看到类的全部信息
Class<?> clazz=Class.forName(path);
System.out.println(clazz.hashCode());
System.out.println(clazz);
System.out.println(clazz.getName());
System.out.println(clazz.getSimpleName());
//获取属性信息
//获取公共的属性
// Field[] fields=clazz.getFields();
// System.out.println(fields.length);
// for(Field field:fields){
// System.out.println(field);
// }
//获取所有属性
Field[] fields=clazz.getDeclaredFields();
Field f=clazz.getDeclaredField("name");
System.out.println(f);
System.out.println(fields.length);
for(Field field:fields){
System.out.println(field);
}
//获取方法信息
Method[] methods=clazz.getDeclaredMethods();
for(Method method:methods){
System.out.println(method);
}
//设置参数类型,用于反射区分方法的类型
Method m=clazz.getDeclaredMethod("setName",String.class);
//获取构造器信息
Constructor[] constructors=clazz.getDeclaredConstructors();
Constructor c=clazz.getDeclaredConstructor(String.class,int.class,int.class);
System.out.println(c);
for(Constructor constructor:constructors){
System.out.println(constructor);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
/**
* 动态通过反射API操作构造器方法,属性
* @author lsd
*/
public class Demo03 {
public static void main(String[] args) {
String path="reflect.User";
//动态操作构造器
try {
Class<User> clazz= (Class<User>) Class.forName(path);
User u=(User) clazz.newInstance();//调用user的无参构造
System.out.println(u);
//通过有参数的构造器实例化对象
Constructor<User> c=clazz.getDeclaredConstructor(String.class,int.class,int.class);
User u2=c.newInstance("lsd",1001,18);
System.out.println(u2.getName());
System.out.println(u2);
//通过反射Api调用普通方法
User u3=clazz.newInstance();
// u3.setName("lsd3");
Method method=clazz.getDeclaredMethod("setName", String.class);
method.invoke(u3,"lsd3");
System.out.println(u3.getName());
//通过反射APi操作属性
Field field=clazz.getDeclaredField("name");
field.setAccessible(true);//不做安全检查,直接访问
field.set(u3, "lsd5");
System.out.println(u3.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
‘反射再一定程度上会很耗费时间,所以’可以调用setAccessible来关闭检查老提高效率。
反射获取参数:
public class Demo04 {
public void test(Map<String,Integer> map){
System.out.println("test()");
}
public static void main(String[] args) {
try {
Method method=Demo04.class.getDeclaredMethod("test", Map.class);
//获取带饭行的参数类型
Type[] types=method.getGenericParameterTypes();
for(Type type:types){
System.out.println(type);
if(type instanceof ParameterizedType){
//对参数进行拆分
Type[] types1=((ParameterizedType) type).getActualTypeArguments();
for(Type type1:types1){
System.out.println(type1);
}
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
/**
- 使用反射读取注解信息,模拟处理注解的流程
- @author lsd
*/
public class Demo03 {
public static void main(String[] args) {
try {
Class clazz=Class.forName("annotation.LsdStudent");
//获取类所有注解
Annotation[] annotations=clazz.getAnnotations();
for(Annotation annotation:annotations){
System.out.println(annotation);
}
//获得类指定注解的值
LsdTable lsdTable= (LsdTable) clazz.getAnnotation(LsdTable.class);
System.out.println(lsdTable.value());
//获得类的属性的注解
Field field=clazz.getDeclaredField("name");
LsdField lsdField= field.getAnnotation(LsdField.class);
System.out.println(lsdField.columnName()+"--"+lsdField.type()+"--"+lsdField.length());
//根据获得表怒部分,字段信息,生成相关表
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}