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