java反射

来源:互联网 发布:apache ab 多个url 编辑:程序博客网 时间:2024/05/29 08:49

1.基本类的反射

package senssic.demo;import java.lang.annotation.Annotation;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;/** * 反射,实例化Class是反射的源头,然后可以反射各个部分 *  * @author Administrator *  */@Retention(RetentionPolicy.RUNTIME)@interface What {String description();}interface B {public void location();}class C {public String place = "安徽阜阳";public void nativePlace() {System.out.println("中国安徽阜阳!");}}@What(description = "annotation反射的一个例子")class A extends C implements B {private String name;private int age;public A() {}public A(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void pp(String name, int age) {System.out.println("普通方法,方法名字:" + name + "方法年龄:" + age);}@Overridepublic String toString() {return "姓名:" + this.name + "年龄:" + this.age;}@Overridepublic void location() {System.out.println("中国安徽池州!");}}public class ReflectClass {public static void main(String[] args) throws Exception {// 实例化Class类的三种方法// 1.使用Class类的静态方法forName(),抛异常Class cl = null;try {cl = Class.forName("senssic.demo.A");} catch (ClassNotFoundException e) {e.printStackTrace();}// 2.使用类.class实例化Class类// / Class cla = A.class;// 3.使用对象.getClass()方法实例化Class类// / A a = new A();// / Class class1 = a.getClass();System.out.println(cl.getName());// 通过反射实例化对象,但被实例化类必须有无参构造方法A a = (A) cl.newInstance();a.setName("senssic");a.setAge(20);System.out.println(a.toString());// 通过反射实例化有参构造类,还可以调用返回Constructor数组的重载函数然后指定那个构造函数,此方法使用的是可变参数的函数指定的构造函数A a2 = (A) cl.getConstructor(String.class, int.class).newInstance("senssic2", 21);System.out.println(a2.toString());// 通过反射获得一个类的结构// 1.获得全部接口for (Class ssalc : cl.getInterfaces()) {System.out.println(ssalc.getName());// 输出接口名字}// 2.获得所有继承的父类System.out.println(cl.getSuperclass());// 输出父类类名// 3.反射获得所有的Annotationfor (Annotation ann : cl.getAnnotations()) {System.out.println(ann.toString());}// 反射得到一个类的结构// 获取所有类属性System.out.println("-------反射得到一个类的结构--------");System.out.println("类中的所有属性:");System.out.println("<---公共属性(实现的接口或者父类中的公共属性)--->");for (Field field : cl.getFields()) {// getFields获得公共属性System.out.print(Modifier.toString(field.getModifiers()));System.out.print("   " + field.getType().getName());System.out.print("   " + field.getName() + "\n");}System.out.println("<---自己类中的属性--->");for (Field field : cl.getDeclaredFields()) {// 获得本类属性System.out.print(Modifier.toString(field.getModifiers()));System.out.print("   " + field.getType().getName());System.out.print("   " + field.getName() + "\n");}// 获取所有构造函数System.out.println("类中所有构造方法:");for (Constructor<A> con : cl.getConstructors()) {// 获得所有类中构造函数System.out.print(Modifier.toString(con.getModifiers()) + "  ");// 获得修饰符并转换为String类型System.out.print(con.getName() + "(");StringBuilder sb = new StringBuilder();for (Class ssalc : con.getParameterTypes()) {sb.append(ssalc.getName() + ",");// 获得参数类型}if (sb.length() != 0) {System.out.print(sb.substring(0, sb.length() - 1));// 如果不为空参数除去最后一个“,”字符}System.out.print("){}\n");}// 获取所有方法System.out.println("类中全部方法:");for (Method method : cl.getMethods()) {System.out.print(Modifier.toString(method.getModifiers()));// 获得修饰符并转换为String类型System.out.print("   " + method.getReturnType().getName());// 获得返回类型System.out.print("   " + method.getName() + "(");StringBuilder sbBuilder = new StringBuilder();for (Class ssalc : method.getParameterTypes()) {// 获取参数类型sbBuilder.append(ssalc.getName() + ",");}if (sbBuilder.length() != 0) {System.out.print(sbBuilder.substring(0, sbBuilder.length() - 1));}if (method.getExceptionTypes().length > 0) {// 判断是否有抛出异常System.out.print(")throws");} else {System.out.print(")");}StringBuilder sBuilder = new StringBuilder();for (Class ssalc : method.getExceptionTypes()) {// 获得异常类型sBuilder.append(ssalc.getName() + ",");}if (sBuilder.length() != 0) {System.out.print(sBuilder.substring(0, sBuilder.length() - 1));}System.out.print("{  }\n");}// 通过反射调用方法(无参)Method method = cl.getMethod("nativePlace");// 获得无参函数method.invoke(cl.newInstance());// 调用// 通过反射调用方法(有参)Method method2 = cl.getMethod("pp", String.class, int.class);// 获得有参函数method2.invoke(cl.newInstance(), "senssic", 22);// 调用// 通过反射调用属性Field nameField = cl.getDeclaredField("name");// 获得本类属性Field ageField = cl.getDeclaredField("age");nameField.setAccessible(true);// 设置私有属(private)性可见ageField.setAccessible(true);Object obj = cl.newInstance();nameField.set(obj, "senssic");// 设置属性ageField.set(obj, 23);System.out.println("通过反射设置属性值:得到的返回的属性值为--->name:" + nameField.get(obj)+ "   age:"// 获得属性值+ ageField.get(obj));// 当然数组也可以被反射,通过Class类结合java.lang.reflect.Array就可以操作了,基本操作都差不多的就不再累赘}}

运行结果:

senssic.demo.A
姓名:senssic年龄:20
姓名:senssic2年龄:21
senssic.demo.B
class senssic.demo.C
@senssic.demo.What(description=annotation反射的一个例子)
-------反射得到一个类的结构--------
类中的所有属性:
<---公共属性(实现的接口或者父类中的公共属性)--->
public   java.lang.String   place
<---自己类中的属性--->
private   java.lang.String   name
private   int   age
类中所有构造方法:
public  senssic.demo.A(){}
public  senssic.demo.A(java.lang.String,int){}
类中全部方法:
public   void   pp(java.lang.String,int){  }
public   void   setAge(int){  }
public   int   getAge(){  }
public   java.lang.String   toString(){  }
public   java.lang.String   getName(){  }
public   void   setName(java.lang.String){  }
public   void   location(){  }
public   void   nativePlace(){  }
public final native   java.lang.Class   getClass(){  }
public native   int   hashCode(){  }
public   boolean   equals(java.lang.Object){  }
public final native   void   notify(){  }
public final native   void   notifyAll(){  }
public final   void   wait(long,int)throwsjava.lang.InterruptedException{  }
public final   void   wait()throwsjava.lang.InterruptedException{  }
public final native   void   wait(long)throwsjava.lang.InterruptedException{  }
中国安徽阜阳!
普通方法,方法名字:senssic方法年龄:22
通过反射设置属性值:得到的返回的属性值为--->name:senssic   age:23


2.泛型类的反射

父类
package senssic.server.base;public class MyclassSuper<Date, Timer> {}
父接口

package senssic.server.base;/** * 其实这里的泛型只是标注,内有任何实在意义,发挥其意义的是在他的实现类,必须指明 *  * @author qiss *  * @param <Timer> * @param <T> */public interface MyclassInter<Timer, T> {}


package senssic.server.base;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.lang.reflect.TypeVariable;import java.sql.Time;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import java.util.TreeSet;class Person {}class Pro {}/** * 其实现类,当继承父类或实现接口时候,他们的泛型必须指明类型,或者也使用泛型,让下一个子类指明,比如此处的J并未指明而是本类也指明泛型 *  * @author qiss *  * @param <T> * @param <K> */@SuppressWarnings("rawtypes")public class MyClass<J, K> extends MyclassSuper<Date, K> implementsMyclassInter<String, J> {private Map<K, Map<List<Person>, Time>> stringList = new HashMap<K, Map<List<Person>, Time>>();private List<Date> list = new ArrayList<Date>();public Set<String> set = new TreeSet<String>();public List<K> lisk = new ArrayList<K>();public Set<J> setj = new TreeSet<J>();public Map<K, Map<List<Person>, Time>> getStringList(List<String> list,Set<List<Pro>> set) {return this.stringList;}public static void main(String[] args) throws Exception {System.out.println("===获取父类的泛型类型===");Type genersupertype = MyClass.class.getGenericSuperclass();if (genersupertype instanceof ParameterizedType) {Type type[] = ((ParameterizedType) genersupertype).getActualTypeArguments();for (int i = 0; i < type.length; i++) {// 如果还是泛型if (type[i] instanceof TypeVariable) {System.out.println(((TypeVariable) type[i]).getName());} else {System.out.println((Class) type[i]);}}}System.out.println("===获取父接口的泛型类型===");// 父接口可能有多个Type genersuperintertype[] = MyClass.class.getGenericInterfaces();for (int i = 0; i < genersuperintertype.length; i++) {if (genersuperintertype[i] instanceof ParameterizedType) {Type type[] = ((ParameterizedType) genersuperintertype[i]).getActualTypeArguments();for (int j = 0; j < type.length; j++) {// 如果还是泛型if (type[j] instanceof TypeVariable) {System.out.println(((TypeVariable) type[j]).getName());} else {System.out.println((Class) type[j]);}}}}System.out.println("===获取方法返回的泛型类型===");Method method = MyClass.class.getMethod("getStringList", List.class,Set.class);Type genericMethodReturn = method.getGenericReturnType();if (genericMethodReturn instanceof ParameterizedType) {Type type[] = ((ParameterizedType) genericMethodReturn).getActualTypeArguments();for (int i = 0; i < type.length; i++) {// 如果还是泛型if (type[i] instanceof TypeVariable) {System.out.println(((TypeVariable) type[i]).getName());} else {// 如果泛型参数还带泛型参数if (type[i] instanceof ParameterizedType) {Type type2[] = ((ParameterizedType) type[i]).getActualTypeArguments();for (int j = 0; j < type2.length; j++) {// 如果泛型参数的参数的参数仍是泛型if (type2[j] instanceof ParameterizedType) {Type type3[] = ((ParameterizedType) type2[j]).getActualTypeArguments();for (int k = 0; k < type3.length; k++) {// 如果还是泛型^^^可以无限循环下去if (type3[k] instanceof TypeVariable) {System.out.println(((TypeVariable) type3[k]).getName());} else {System.out.println((Class) type3[k]);}}} else {System.out.println((Class) type2[j]);}}}}}}System.out.println("===获取方法参数的泛型类型===");Method methGengraPramem = MyClass.class.getMethod("getStringList",List.class, Set.class);Type[] types = methGengraPramem.getGenericParameterTypes();for (int l = 0; l < types.length; l++) {if (types[l] instanceof ParameterizedType) {Type type[] = ((ParameterizedType) types[l]).getActualTypeArguments();for (int i = 0; i < type.length; i++) {// 如果还是泛型if (type[i] instanceof TypeVariable) {System.out.println(((TypeVariable) type[i]).getName());} else {// 如果泛型参数还带泛型参数if (type[i] instanceof ParameterizedType) {Type type2[] = ((ParameterizedType) type[i]).getActualTypeArguments();for (int j = 0; j < type2.length; j++) {// 如果泛型参数的参数的参数仍是泛型if (type2[j] instanceof ParameterizedType) {Type type3[] = ((ParameterizedType) type2[j]).getActualTypeArguments();for (int k = 0; k < type3.length; k++) {// 如果还是泛型^^^可以无限循环下去if (type3[k] instanceof TypeVariable) {System.out.println(((TypeVariable) type3[k]).getName());} else {System.out.println((Class) type3[k]);}}} else {System.out.println((Class) type2[j]);}}} else {System.out.println((Class) type[i]);}}}} else {System.out.println((Class) types[l]);}}System.out.println("===获取保护字段的泛型参数类型===");Field field[] = MyClass.class.getDeclaredFields();for (int i = 0; i < field.length; i++) {Type type = field[i].getGenericType();// 如果是泛型参数if (type instanceof ParameterizedType) {Type type2[] = ((ParameterizedType) type).getActualTypeArguments();for (int j = 0; j < type2.length; j++) {if (type2[j] instanceof TypeVariable) {System.out.println(((TypeVariable) type2[j]).getName());} else {if (type2[j] instanceof ParameterizedType) {Type type3[] = ((ParameterizedType) type2[j]).getActualTypeArguments();for (int k = 0; k < type3.length; k++) {if (type3[k] instanceof TypeVariable) {System.out.println(((TypeVariable) type3[k]).getName());} else {if (type3[k] instanceof ParameterizedType) {Type type4[] = ((ParameterizedType) type3[k]).getActualTypeArguments();for (int m = 0; m < type4.length; m++) {// ^^^可以无限循环下去if (type4[m] instanceof TypeVariable) {System.out.println(((TypeVariable) type4[m]).getName());} else {System.out.println((Class) type4[m]);}}} else {System.out.println((Class) type3[k]);}}}} else {System.out.println((Class) type2[j]);}}}}}System.out.println("===获取公共字段的泛型参数类型===");Field fields[] = MyClass.class.getFields();for (int i = 0; i < fields.length; i++) {Type pubfilegenera = fields[i].getGenericType();if (pubfilegenera instanceof ParameterizedType) {Type type[] = ((ParameterizedType) pubfilegenera).getActualTypeArguments();for (int j = 0; j < type.length; j++) {if (type[j] instanceof TypeVariable) {System.out.println(((TypeVariable) type[j]).getName());} else {System.out.println((Class) type[j]);}}}}}}

运行结果:

===获取父类的泛型类型===
class java.util.Date
K
===获取父接口的泛型类型===
class java.lang.String
J
===获取方法返回的泛型类型===
K
class senssic.server.base.Person
class java.sql.Time
===获取方法参数的泛型类型===
class java.lang.String
class senssic.server.base.Pro
===获取保护字段的泛型参数类型===
K
class senssic.server.base.Person
class java.sql.Time
class java.util.Date
class java.lang.String
K
J
===获取公共字段的泛型参数类型===
class java.lang.String
K
J