
1 package com.demo.bean; 2 3 import java.util.Date; 4 5 public class User { 6 public String name; 7 private int age; 8 9 public User() {} 10 11 public User(String name, int age) { 12 super(); 13 this.name = name; 14 this.age = age; 15 } 16 17 public String getName() { 18 return name; 19 } 20 public void setName(String name) { 21 this.name = name; 22 } 23 public int getAge() { 24 return age; 25 } 26 public void setAge(int age) { 27 this.age = age; 28 } 29 public String show() { 30 return "User [name=" + name + ", age=" + age + "]"; 31 } 32 33 }
1 User u = new User();2 Class clazz01 = Class.forName("com.demo.bean.User"); 3 Class clazz02 = u.getClass(); 4 Class clazz03 = u.class;
通过class获得类名,属性,方法,构造器对象
Class clazz = Class.forName("com.demo.bean.User");
// 包名+类名 Class className = clazz.getName();
// 类名 String simpleName = clazz.getSimpleName(); // 返回一个public 的属性对象 Field Field nameField = clazz.getField("name"); // 返回包含所有的public 属性数组 Field[] Field[] fields = clazz.getFields(); // 返回一个 的属性对象 Field(包括private) Field pwdField = clazz.getDeclaredField("age"); // 返回包含所有的 属性数组(包括private) Field[] declaredFields = clazz.getDeclaredFields(); // 通过方法名字和参数获得方法对象 Method method = clazz.getDeclaredMethod("getAge"); Method method02 = clazz.getDeclaredMethod("setAge",int.class); // 获得所有方法 Method[] methods = clazz.getDeclaredMethods(); // 通过参数获得构造器对象 Constructor ctr01 = clazz.getDeclaredConstructor(); Constructor ctr02 = clazz.getDeclaredConstructor(String.class,int.class); // 获得所有构造器对象 Constructor[] ctrs = clazz.getDeclaredConstructors(); // 产生无参数构造,javabean必须要有无参数构造 User use02 = (User) clazz.newInstance();
反射生成对象和调用方法
package com.demo.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import com.demo.bean.User; public class Demo01 { public static void main(String[] args) throws Exception { Class clazz = User.class; // 无参对象 User u1 = (User) clazz.newInstance(); // 有参对象 Constructor ctr = clazz.getDeclaredConstructor(String.class,int.class); User u2 = (User) ctr.newInstance("ouyangri",21); // 获得setName,并调用 Method method02 = clazz.getDeclaredMethod("setName",String.class); method02.invoke(u2,"小红"); // 获得getName,并调用 Method method = clazz.getDeclaredMethod("getName"); // 私有方法必须设置为可访问 method.setAccessible(true); String name = (String) method.invoke(u2); // 获得属性 Field f = clazz.getDeclaredField("age"); // 私有属性必须设置为可访问 f.setAccessible(true); // 设置属性值 f.set(u2, 24); // 获得属性值 int age = (int) f.get(u2); } }
注意: 如果需要频繁的用反射访问属性或者方法,应该设置 setAccessible(true),减少安全性检查,提高效率。

package com.demo.reflect; import java.lang.reflect.Method; import java.lang.reflect.TypeVariable; import com.demo.bean.User; public class Demo01 { public static void main(String[] args) throws Exception { for(int i = 0;i < 5;i++) { test01();//普通方法调用 test02();// 安全行检查反射方法调用 test03();// 无安全行检查,反射方法调用 System.out.println("#######################################"); } } // 普通方法调用 public static void test01() { long start = System.currentTimeMillis(); User u = new User(); for(int i = 0;i < 1000000000L;i++) u.getName(); long end = System.currentTimeMillis(); System.out.println("普通方法调用:执行十亿次: "+(double)(end-start)/1000); } // 安全行检查反射方法调用 public static void test02() throws Exception{ long start = System.currentTimeMillis(); User u = new User(); Method method = u.getClass().getMethod("getName"); for(int i = 0;i < 1000000000;i++) method.invoke(u); long end = System.currentTimeMillis(); System.out.println("安全行检查反射方法调用:执行十亿次: "+(double)(end-start)/1000); } // 无安全行检查,反射方法调用 public static void test03() throws Exception{ long start = System.currentTimeMillis(); User u = new User(); Method method = u.getClass().getMethod("getName"); method.setAccessible(true); for(int i = 0;i < 1000000000;i++) method.invoke(u); long end = System.currentTimeMillis(); System.out.println("无安全行检查,反射方法调用:执行十亿次: "+(double)(end-start)/1000); } }
Console:
普通方法调用:执行十亿次: 0.352
安全性检查反射方法调用:执行十亿次: 1.422
无安全性检查,反射方法调用:执行十亿次: 0.833
#######################################
普通方法调用:执行十亿次: 0.354
安全性检查反射方法调用:执行十亿次: 1.384
无安全性检查,反射方法调用:执行十亿次: 0.817
#######################################
普通方法调用:执行十亿次: 0.353
安全性检查反射方法调用:执行十亿次: 1.253
无安全性检查,反射方法调用:执行十亿次: 0.678
#######################################
普通方法调用:执行十亿次: 0.346
安全性检查反射方法调用:执行十亿次: 1.233
无安全性检查,反射方法调用:执行十亿次: 0.678
#######################################
普通方法调用:执行十亿次: 0.343
安全性检查反射方法调用:执行十亿次: 1.24
无安全性检查,反射方法调用:执行十亿次: 0.689
#######################################
反射操作泛型(generic)
Type 是Java编程语言中所有类型的通用超级接口。 这些包括原始类型,参数化类型,数组类型,类型变量和原始类型。
ParameterizedType 表示一个参数化类型,如Collection <String>。
GenericArrayType 表示参数化类型或类型变量的数组类型。
package com.demo.reflect; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; public class Demo01 { public static void main(String[] args) throws Exception { //test01(); //test02(); //test03(); } // 获得方法参数下的参数化类型 static void test01() throws Exception { Class clazz = Class.forName("com.demo.reflect.GenericTest"); GenericTest gt = (GenericTest) clazz.newInstance(); Method method = clazz.getMethod("test01",Map.class,LinkedList.class,String.class); // 获取test01方法下所有的参数化类型 参数 Type[] genericParameterTypes = method.getGenericParameterTypes(); for(Type t:genericParameterTypes) { // 如果是参数化类型,就打印 if(t instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) t; System.out.println("参数化类型:"+ptype.getTypeName()); // 获取参数化类型下所有的 具体类型 Type[] actualTypeArguments = ptype.getActualTypeArguments(); for(Type tt:actualTypeArguments) { System.out.println(" "+tt.getTypeName()); } } } } // 获得方法返回值的参数化类型 static void test02() throws Exception { Class clazz = Class.forName("com.demo.reflect.GenericTest"); GenericTest gt = (GenericTest) clazz.newInstance(); Method method = clazz.getMethod("test01",Map.class,LinkedList.class,String.class); // 获取test01方法返回值下所有的参数化类型 参数 Type t = method.getGenericReturnType(); if(t instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) t; System.out.println("参数化类型:"+ptype.getTypeName()); // 获取参数化类型下所有的 具体类型 Type[] actualTypeArguments = ptype.getActualTypeArguments(); for(Type tt:actualTypeArguments) { System.out.println(" "+tt.getTypeName()); } } } // 获得属性的参数化类型 static void test03() throws Exception { Class clazz = Class.forName("com.demo.reflect.GenericTest"); GenericTest gt = (GenericTest) clazz.newInstance(); Field[] fields = clazz.getDeclaredFields(); for(Field f:fields) { f.setAccessible(true); if(f.getGenericType() instanceof ParameterizedType) { ParameterizedType ptype = (ParameterizedType) f.getGenericType(); System.out.println(ptype.getTypeName()); // 获取参数化类型下所有的 具体类型 Type[] actualTypeArguments = ptype.getActualTypeArguments(); for(Type tt:actualTypeArguments) { System.out.println(" "+tt.getTypeName()); } } } } } class GenericTest{ private HashMap<String,Integer> map; private LinkedList<Double> list; GenericTest(){}; public Map<String,Integer> test01(Map<String,Integer> map,LinkedList<Double> list,String str) { return null; }; }
反射操作注解
package com.demo.reflect; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Field; @SuppressWarnings("all") public class Demo03 { public static void main(String[] args) throws Exception{ Class clazz = Class.forName("com.demo.reflect.User"); User u = (User) clazz.newInstance(); System.out.println("############## 获得类上所有的注解##############"); // 获得类上所有的注解 Annotation[] annotations = clazz.getAnnotations(); for(Annotation an : annotations) { System.out.println(an); } System.out.println("############## 获得类上指定名称的注解##############"); // 获得类上指定名称的注解 Myannotation myat = (Myannotation) clazz.getAnnotation(Myannotation.class); String tableName = myat.value(); System.out.println("tableName: "+tableName); // 获得指定名称字段的注解 System.out.println("##############获得指定名称字段的注解###############"); Field field = clazz.getDeclaredField("username"); Myannotation myat02 = field.getAnnotation(Myannotation.class); System.out.println("columnName: "+myat02.columnName()); System.out.println("type: "+myat02.type()); System.out.println("length: "+myat02.length()); // 获得字段下所有的注解 System.out.println("##############获得字段下所有的注解###############"); Field[] fields = clazz.getDeclaredFields(); for(Field f : fields) { Myannotation myat03 = f.getAnnotation(Myannotation.class); System.out.println("columnName: "+myat03.columnName()); System.out.println("type: "+myat03.type()); System.out.println("length: "+myat03.length()); } } } // 元注解@Target,描述注解可以作用的范围 @Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD}) // 元注解@@Retention,描述注解保留时期 @Retention(RetentionPolicy.RUNTIME) @interface Myannotation { /* 格式: 类型 属性名() [default 属性值] */ String columnName() default ""; String type() default ""; // 带有默认值可以不进行赋值操作 int length() default -1; /* 如果属性是 value 默认不通过属性名赋值 ex: Myannotation("xxxx") == Myannotation(value="xxxx") */ String value() default ""; } @Myannotation("user") class User{ @Myannotation(columnName="username",type="varchar",length=20) private String username; @Myannotation(columnName="pwd",type="varchar",length=20) private String pwd; public User() { super(); } public User(String username, String pwd) { super(); this.username = username; this.pwd = pwd; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } }