一:获得Class对象
获取Class对象的三种方式
Class类和一般类不同,不能通过new来实例对象,它的实例对象就是类在内存中的字节码,所以Class类的实例过程就是类获取字节码的过程。
1、调用某个类的 class 属性获取 Class 对象
如:Date.class 会返回 Date 类对应的 Class对象(其实就是得到一个类的一份字节码文件);
2、使用 Class 类的 forName(String className)静态方法,className 表示全限定名
如:Class.forName("java.lang.String")
3、调用某个对象的 getClass()方法。该方法属于 Object 类
如:new Date().getClass();
九个预定义Class实例对象:八个基本数据类型,void
Class<?> in1 = int.class; //int
Class<?> in2 = Integer.class; //class java.lang.Integer
//包装类都有一个常量TYPE,用来表示其基本数据类型的字节码
Class<?> in3 = Integer.TYPE; //int
System.out.println(in3 == in1);//true
System.out.println(in3 == in2);//false
//数组类型的 Class 实例对象:
Class<String[]> s = String[].class;
Class<int[]> i = int[].class;
二:利用 Class 对象获取类的属性信息
Class clazz = Class.forName("java.lang.String");
System.out.println(clazz.getPackage()); //包名package java.lang, Java Platform API Specification, version 1.7
System.out.println(clazz.getName()); //全限定名java.lang.String
System.out.println(clazz.getSimpleName()); //类的简称String
System.out.println(clazz.getSuperclass()); //父类class java.lang.Object
System.out.println(clazz.getInterfaces()); //接口数组[Ljava.lang.Class;@4a0b1298
for (Class cla : clazz.getInterfaces()) {
System.out.println(cla);
//interface java.io.Serializable
//interface java.lang.Comparable
//interface java.lang.CharSequence
}
三:利用 Class 对象获取构造方法 Constructor
Constructor<T> getConstructor(Class<?>... parameterTypes)
根据构造函数的参数,返回一个具体的具有public属性的构造函数;
如:Constructor constructor = String.class.getConstructor(StringBuffer.class);
String str = (String)constructor.newInstance(new StringBuffer("abc"));
Constructor<?>[] getConstructors()
返回所有具有public属性的构造函数数组;
如:Constructor[] constructors = Class.forName("java.lang.String").getConstructors();
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性,和访问权限无关);
Constructor<?>[] getDeclaredConstructors()
返回该类中所有的构造函数数组(不分public和非public属性,和访问权限无关);
四:利用 Class 对象获取成员方法 Method
Method getMethod(String name, Class<?> ... parameterTypes)
根据方法名和参数,返回该 Class 对象表示类和其父类的指定的 public 方法;
如:Method charAt = String.class.getMethod(“charAt”,int.class);
Method[] getMethods():
返回该 Class 对象表示类和其父类的所有 public 方法;
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
根据方法名和参数,返回该 Class 对象表示类的指定的方法。和访问权限无关,但不包括继承的方法;
Method[] getDeclaredMethods():
获得类所有的方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法;
五:利用 Class 对象获取成员变量 Field
Field getField(String name)
根据变量名,返回一个具体的具有public属性的成员变量
Field[] getFields()
返回具有public属性的成员变量的数组
Field getDeclaredField(String name)
根据变量名,返回一个成员变量(不分public和非public属性,和访问权限无关)
Field[] getDelcaredFields()
返回所有成员变量组成的数组(不分public和非public属性,和访问权限无关)
例:获取和更改某个对象的私有字段
Class<Student> clz = Student.class;
Student stu = clz.newInstance("Tom",22); //创建Student的实例对象
Field f1 = clz.getDeclaredField("name"); //获取Student类的name变量
f1.setAccessible(true); //将name设置成可访问的
Object obj = f1.get(stu); //从stu对象上获取name属性的值
f1.set(stu, "Jim"); //修改stu对象的name属性值为Jim
Field f2 = clz.getDeclaredField("age"); //获取Student类的name变量
f2.setAccessible(true); //将age设置成可访问的
int age = f2.getInt(stu); //从stu对象上获取age属性的值
f2.set(stu, 21); //修改stu对象的age属性值为21
六:利用 Class 对象获取泛型信息
Class<Student> clz = Student.class;
Field f = clz.getDeclaredField("map"); //获取Student类的map变量
// Class<?> getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
Class cl = f.getType(); //interface java.util.Map
//Type getGenericType() 返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型(包含泛型的类型)。
Type t = f.getGenericType(); //java.util.Map<java.lang.String, java.lang.Integer>
//Type这个类里面没有任何方法,所以需要调用子类的方法,大类型转到小类型,需要强转!
ParameterizedType pt = (ParameterizedType)t;
/**
* Type[] getActualTypeArguments()
返回泛型参数类型
* Type getOwnerType()
返回 Type 对象,表示此类型是其成员之一的类型。
* Type getRawType()
返回被泛型限制的变量的类型
*/
t = pt.getRawType(); //interface java.util.Map
Type[] ts = pt.getActualTypeArguments();
for (Type type : ts) {
System.out.println(type);
//class java.lang.String
//class java.lang.Integer
}
七:利用 Class 对象获取注解信息
//自定义注解类
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface MyAnnotation {
int value();
}
//使用注解类
public class MyBean {
@MyAnnotation(20)
private int value;
@Override
public String toString() {
return String.valueOf(value);
}
}
//反射注解
public static void main(String[] args) {
try {
Field field = MyBean.class.getDeclaredField("value");//获取变量value
field.setAccessible(true);//将value设置成可访问的
if(field.isAnnotationPresent(MyAnnotation.class)){//判断成员变量是否有注解
MyAnnotation myAnnotation = field.getAnnotation(MyAnnotation.class);//获取定义在成员变量中的注解MyAnnotation
int value = myAnnotation.value();//获取定义在MyBean的MyAnnotation里面value属性值
System.out.println(value);//20
Class<MyBean> clz = MyBean.class;
MyBean myBean = clz.newInstance(); //创建MyBean实例对象
field.setInt(myBean, value);//将注解的值20可以赋给成员变量
System.out.println(myBean);//验证结果20
}
} catch (Exception e) {
e.printStackTrace();
};
}