1、java反射
Class类与java.lang.reflect类库一起对反射的概念进行了支持。该类库包含了Filed,Method和Constructor类(每个类都实现了member接口)。这些类型的对象是由jvm在运行时创建的,用来表示未知类里对应的成员。这样可以使用Constructor创建新的对象,用get()和set()方法读取和修改Field对象关联的字段,用invoke()方法调用与Method对象关联的方法。这样,匿名对象的类信息就能在运行时被完全确定下来,而在编译时不需要知道任何类型信息。
当通过反射与一个未知类型的对象打交道时,jvm只是简单的检查这个对象,看它属于哪个特定的类。在用它做其他事情之前必须先加载那个类的Class对象。因此,那个类的.class文件对于jvm来说必须是可获取的:要么在本地机器上,要么可以通过网络取得。所以,对于不是利用反射来说(普通方式调用对象的所有方法),编译器在编译时打开和检查.class文件。而对于反射,.class文件在编译时是不可获取的,是在运行时打开和检查.class文件,获取类型信息的。
总的来说反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2、反射的作用
(1)在运行时判断任意一个对象所属的类
(2)在运行时构造任意一个类的对象
(3)在运行时判断任意一个类所具有的成员变量和方法
(4)在运行时调用任意一个对象的方法
(5)生成动态代理
3、代码展示
//反射机制的相关API测试调用
public class Test1 {
public static void main(String[] agrs) throws Exception{
Class<?> classType = ExtendType.class;
//1、通过一个对象获得完整的包名
//System.out.println(classType.getName());//com.dennyac.HbaseTest.reflect.ExtendType
//2、实例化Class类对象的三种方法
// Class<?> class1 = null;
// Class<?> class2 = null;
// Class<?> class3 = null;
// // 运用static method Class.forName()
// class1 = Class.forName("com.dennyac.HbaseTest.reflect.ExtendType");
// //调用getClass
// class2 = new ExtendType().getClass();
// //运用.class 语法
// class3 = ExtendType.class;
// System.out.println("类名称 " + class1.getName());
// System.out.println("类名称 " + class2.getName());
// System.out.println("类名称 " + class3.getName());
//3、获取一个对象的父类与实现的接口
// Class<?> clazz = Class.forName("com.dennyac.HbaseTest.reflect.ExtendType");
// // 取得父类
// Class<?> parentClass = clazz.getSuperclass();
// System.out.println("clazz的父类为:" + parentClass.getName());
// //clazz的父类为:com.dennyac.HbaseTest.reflect.Type
//
// // 获取所有的接口
// Class<?> intes[] = clazz.getInterfaces();
// System.out.println("clazz实现的接口有:");
// for (int i = 0; i < intes.length; i++) {
// System.out.println((i + 1) + ":" + intes[i].getName());
// }
//4、获取某个类中的全部构造函数
// 4.1 使用getConstructors获取构造器,取得全部的构造函数
// Constructor<?>[] constructors = classType.getConstructors();
// for (Constructor<?> m : constructors) {
// System.out.println(m);
// }
// // 4.2 查看每个构造方法需要的参数
// for (int i = 0; i < constructors.length; i++) {
//
// Class<?> clazzs[] = constructors[i].getParameterTypes();
// System.out.print("cons[" + i + "] (");
// for (int j = 0; j < clazzs.length; j++) {
// if (j == clazzs.length - 1)
// System.out.print(clazzs[j].getName());
// else
// System.out.print(clazzs[j].getName() + ",");
// }
// System.out.println(")");
// }
//
// // 4.3 使用getDeclaredConstructors获取构造器
// constructors = classType.getDeclaredConstructors();
// for (Constructor<?> m : constructors) {
// System.out.println(m);
// }
//5、获取某个类的全部属性
// System.out.println("==========实现的接口或者父类的属性==========");
// // 5.1 使用getFields获取属性
// Field[] fields = classType.getFields();
// for (Field f : fields) {
// System.out.println(f);
// }
//
// System.out.println("===============本类属性===============");
// // 5.2 使用getDeclaredFields获取属性
// fields = classType.getDeclaredFields();
// for (Field f : fields) {
// System.out.println(f);
// }
//
// System.out.println("===============实现的接口或者父类的属性的权限修饰符===============");
// // 5.3 获取某个类的属性的权限修饰符
// Field[] filed1 = classType.getFields();
// for (int j = 0; j < filed1.length; j++) {
// // 权限修饰符
// int mo = filed1[j].getModifiers();
// String priv = Modifier.toString(mo);
// // 属性类型
// Class<?> type = filed1[j].getType();
// System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";");
// }
/*getFields和getDeclaredFields区别:
getFields返回的是申明为public的属性,包括父类中定义,
getDeclaredFields返回的是指定类定义的所有定义的属性,不包括父类的。
*/
//6、 获取某个类的全部方法
// 6.1 使用getMethods获取方法
// Method[] methods = classType.getMethods();
// System.out.println("getMethods()");
// for (Method m : methods) {
// System.out.println(m);
// }
//
// System.out.println();
//
// // 6.2 使用getDeclaredMethods获取方法
// methods = classType.getDeclaredMethods();
// System.out.println("getDeclaredMethods()");
// for (Method m : methods) {
// System.out.println(m);
// }
}
}
//Type类
public class Type{
public int pubIntField;
public String pubStringField;
private int prvIntField;
public Type(){
Log("Default Constructor");
}
Type(int arg1, String arg2){
pubIntField = arg1;
pubStringField = arg2;
Log("Constructor with parameters");
}
public void setIntField(int val) {
this.prvIntField = val;
}
public int getIntField() {
return prvIntField;
}
private void Log(String msg){
System.out.println("Type:" + msg);
}
}
//ExtendType类
public class ExtendType extends Type {
public int pubIntExtendField;
public String pubStringExtendField;
private int prvIntExtendField;
public ExtendType(){
Log("Default Constructor");
}
public ExtendType(int arg1, String arg2){
pubIntExtendField = arg1;
pubStringExtendField = arg2;
Log("Constructor with parameters");
}
public void setIntExtendField(int field7) {
this.prvIntExtendField = field7;
}
public int getIntExtendField() {
return prvIntExtendField;
}
private void Log(String msg){
System.out.println("ExtendType:" + msg);
}
}