java反射

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);
	}

	@Override
	public String toString() {
		return "姓名:" + this.name + "年龄:" + this.age;
	}

	@Override
	public 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.反射获得所有的Annotation
		for (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> implements
		MyclassInter<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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值