JAVA反射机制
一、JAVA反射机制的概念:
在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、功能:
在程序运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
三、API使用示例
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** * 反射学习笔记 */ public class ReflectDemo { public static void main(String[] args) { try { //获得Class对象的三种方式 //方式一: Class class1 = int.class; //8个基本数据类型和一个特殊类型void获取Class对象的方式 class1 = Cat.class; //包装类的获取方式 class1 = Integer.class; class1 = Integer.TYPE; //方式二: //引用类型 class1 = "abc".getClass(); class1 = new String().getClass(); class1 = new Cat().getClass(); //方式三: class1 = Class.forName("java.lang.String"); //基本类型和包装类型的Class对象 Class<Boolean> booleanClass = boolean.class; Class<Boolean> booleanClass2 = Boolean.TYPE; //比较的是内存中的字节码文件,而非字节码文件中的内容 System.out.println("boolean.class==Boolean.TYPE: " + (booleanClass == booleanClass2)); Class<Byte> byteClass = byte.class; Class<Byte> byteClass2 = Byte.TYPE; System.out.println("byte.class==Byte.TYPE: " + (byteClass == byteClass2)); Class<Character> charClass = char.class; Class<Character> charClass2 = Character.TYPE; System.out.println("char.class==Character.TYPE: " + (charClass == charClass2)); Class<Short> shortClass = short.class; Class<Short> shortClass2 = Short.TYPE; System.out.println("short.class==Short.TYPE: " + (shortClass == shortClass2)); Class<Integer> integerClass = Integer.TYPE; Class<Integer> intClass = int.class; System.out.println("int.class==Integer.TYPE: " + (intClass == integerClass)); Class<Long> longClass = long.class; Class<Long> longClass2 = Long.TYPE; System.out.println("long.class==Long.TYPE: " + (longClass == longClass2)); Class<Float> floatClass = float.class; Class<Float> floatClass2 = Float.TYPE; System.out.println("float.class==Float.TYPE: " + (floatClass == floatClass2)); Class<Double> doubleClass = double.class; Class<Double> doubleClass2 = Double.TYPE; System.out.println("double.class==Double.TYPE: " + (doubleClass == doubleClass2)); Class<Void> voidClass = void.class; Class<Void> voidClass2 = Void.TYPE; System.out.println("void.class==Void.TYPE: " + (voidClass == voidClass2)); System.out.println("int[][].class == int[][].class: " + (int[][].class == int[][].class)); //判断数据类型 System.out.println("int.class.isPrimitive(): " + int.class.isPrimitive()); //判断是否基本数据类型 System.out.println("Integer.class.isPrimitive(): " + Integer.class.isPrimitive()); System.out.println("int[].class.isPrimitive(): " + int[].class.isPrimitive()); System.out.println("int[].class.isArray(): " + int[].class.isArray()); //判断是否数组类型 System.out.println("---------------------------------------"); Class<Cat> classz = Cat.class; // 调用无参的公共构造方法 Constructor<Cat> constructor = classz.getConstructor(null); Cat cat = constructor.newInstance(null); // 调用带参数的公有构造方法 constructor = classz.getConstructor(String.class); cat = constructor.newInstance("汤姆猫"); System.out.println(cat.getName()); //调用带参的私有构造方法 constructor = classz.getDeclaredConstructor(String.class,String.class); constructor.setAccessible(true); cat = constructor.newInstance("不吃老鼠的猫","黄猫"); //获得一个属性的值(公共的) Field fieldName = classz.getField("name"); System.out.println(fieldName.get(cat)); fieldName.set(cat, "美猫猫"); System.out.println(fieldName.get(cat)); //私有的 fieldName = classz.getDeclaredField("type"); fieldName.setAccessible(true); fieldName.set(cat,"挪威森林猫"); System.out.println(fieldName.get(cat)); //调用无参的公共方法 Method method = classz.getMethod("catchMouse", null); method.invoke(cat, null); //调用带参的公共方法 method = classz.getMethod("eat", String.class); method.invoke(cat, "鱼"); //调用私有方法 method = classz.getDeclaredMethod("display", null); method.setAccessible(true); method.invoke(cat, null); //调用带数组参数的方法 Class arraysClass = Class.forName("java.util.Arrays"); //加载内存中java.util.Arrays的Class字节码文件 Method arrayMethod = arraysClass.getMethod("sort", int[].class); int[] nums = {3,5,9,2,6,10}; arrayMethod.invoke(null, nums); //因为sort是java.util.Arrays类的静态方法,不需要实例对象,所以第一个参数为null arrayMethod = arraysClass.getMethod("toString", int[].class); System.out.println(arrayMethod.invoke(null, nums)); //打印排序后的数组 //获得父类信息 System.out.println(classz.getSuperclass().getName()); //获得父类的名称 Class superClass = classz.getSuperclass(); Method[] methods = superClass.getDeclaredMethods(); //获得父类的所有方法,包括私有方法 for (Method method2 : methods) { System.out.print(method2.getName() + " "); } System.out.println(); //判断是否抽象类,用java.lang.reflect.Modifier类可以获得一个类中成员的访问修饰符 int modifier = superClass.getModifiers(); System.out.println(Modifier.isAbstract(modifier)); //获得父类的所有属性,包括私有的 Field[] fields = superClass.getDeclaredFields(); for (Field field : fields) { System.out.print(field + " "); } System.out.println(); } catch (Exception e) { e.printStackTrace(); } } } /** * 动物 */ abstract class Animal { /** * 名称 */ public String name; /** * 颜色 */ private String color; /** * 年龄 */ private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } /** * 吃东西 * * @param name */ public abstract void eat(String name); } /** * 猫 * */ class Cat extends Animal { /** * 猫的种类 */ private String type; public Cat() { System.out.println("Cat"); } private Cat(String name,String type) { this.name = name; this.type = type; } public Cat(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } /** * 抓老鼠 */ public void catchMouse() { System.out.println("抓老鼠。。。"); } @Override public void eat(String foodName) { System.out.println("猫吃" + foodName + "。"); } /** * 显示猫的名称 */ private void display() { System.out.println("name:" + name); } }