反射机制
来源:互联网 发布:北京全国接单淘宝贷款 编辑:程序博客网 时间:2024/05/22 06:42
反射
能够分析“类”(不是对象)能力的程序称为反射(reflective)
- 运行中分析类的能力
- 运行中查看对象
- 实现通用的数组操纵代码
- 利用Method对象
Class 类
在程序运行期间,Java运行时系统始终为 所以对象维护一个 被称为运行时的类型标识。这个
信息跟踪着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。
Object类中的getClass()
方法将会返回一个Class类型的实例。
如下是源代码,该方法是一个不被允许重写的方法。
/** * Returns the runtime class of this {@code Object}. The returned * {@code Class} object is the object that is locked by {@code * static synchronized} methods of the represented class. * * <p><b>The actual result type is {@code Class<? extends |X|>} * where {@code |X|} is the erasure of the static type of the * expression on which {@code getClass} is called.</b> For * example, no cast is required in this code fragment:</p> * * <p> * {@code Number n = 0; }<br> * {@code Class<? extends Number> c = n.getClass(); } * </p> * * @return The {@code Class} object that represents the runtime * class of this object. * @see Class Literals, section 15.8.2 of * <cite>The Java™ Language Specification</cite>. */ public final native Class<?> getClass();
三种获得* 类类型 *实例 的方法
Object object = new Test();System.out.println(object.getClass().getName()); // 将会输出 yang.Test (yang是我的包名字)String className = "java.util.Date";Class c1 = Class.forName(className); // 获得当前类类型信息Class c1 = Date.class;
一个Class
对象实际上表示的是一个类型,而这个类型未必一定是一种类。例如:int.class
虚拟机为* 每种类型(基本类型到每一个类)* 管理一个Class
对象
Class c = int.classc = Enum.class c = void.classc = boolean.classc = double.classc = float.classc = Float.classc = new Float(3.4F).getClassc = Class.forName("java.awt.Button")public @interface Ann {}c = Ann.class;// 类型:从基本类型、甚至 void 、boolean类型到数组 int[] 到类到接口到枚举enum到注解都是类型,每种类型都有一个Class对象维护信息。//我们不可以访问这个对象(因为是私有的),它是由虚拟机生成的,引用这个对象方式非常多(如上)。// <基类和子类是两种类型>有两个Class对象。
if(e.getClass() == EObject.class) //判断对象`e`是不是`EObject`类类型的对象
利用反射分析类的能力
java.lang.reflect
Field Method Constructor
分别用于描述类的域、方法、构造器
public class ReflectionTest{ public static void main(String[] args) { // read class name from command line args or user input String name; if (args.length > 0) name = args[0]; else { Scanner in = new Scanner(System.in); System.out.println("Enter class name (e.g. java.util.Date): "); name = in.next(); } try { // print class name and superclass name (if != Object) Class cl = Class.forName(name); Class supercl = cl.getSuperclass(); String modifiers = Modifier.toString(cl.getModifiers()); if (modifiers.length() > 0) System.out.print(modifiers + " "); System.out.print("class " + name); if (supercl != null && supercl != Object.class) System.out.print(" extends " + supercl.getName()); // Java是单进程方式,所以“实现接口”不算继承方法,只算一种多态性质。 System.out.print("\n{\n"); printConstructors(cl); System.out.println(); printMethods(cl); System.out.println(); printFields(cl); System.out.println("}"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.exit(0); } public static void printConstructors(Class cl) { Constructor[] constructors = cl.getDeclaredConstructors(); for (Constructor c : constructors) { String name = c.getName(); System.out.print(" "); String modifiers = Modifier.toString(c.getModifiers()); if (modifiers.length() > 0) System.out.print(modifiers + " "); System.out.print(name + "("); // print parameter types Class[] paramTypes = c.getParameterTypes(); for (int j = 0; j < paramTypes.length; j++) { if (j > 0) System.out.print(", "); System.out.print(paramTypes[j].getName()); } System.out.println(");"); } } public static void printMethods(Class cl) { Method[] methods = cl.getDeclaredMethods(); for (Method m : methods) { Class retType = m.getReturnType(); String name = m.getName(); System.out.print(" "); // print modifiers, return type and method name String modifiers = Modifier.toString(m.getModifiers()); if (modifiers.length() > 0) System.out.print(modifiers + " "); System.out.print(retType.getName() + " " + name + "("); // print parameter types Class[] paramTypes = m.getParameterTypes(); for (int j = 0; j < paramTypes.length; j++) { if (j > 0) System.out.print(", "); System.out.print(paramTypes[j].getName()); } System.out.println(");"); } } public static void printFields(Class cl) { Field[] fields = cl.getDeclaredFields(); for (Field f : fields) { Class type = f.getType(); String name = f.getName(); System.out.print(" "); String modifiers = Modifier.toString(f.getModifiers()); if (modifiers.length() > 0) System.out.print(modifiers + " "); System.out.println(type.getName() + " " + name + ";"); } }}
复制数组的好方法
public static Object[] badCopyOf(Object a[], int newLength) { Object[] newArray = new Object[newLength]; // 一个对象数组无法转换成实际对象数组 // 设有数组 A[] array = new A[10]; // array是一对象(类型为数组,元素类型为A) // Object[] arrayTemp = (Object[]) array; // 这是可以的 // Object arrayT = (Object) array; // 可以 // 上述也可以转回去,我们始终要关注 new 的实际对象是谁(反射是最好的查看机制)。// 阿猫阿狗(Object)都可以看家,但这个家究竟是谁的?利用反射机制。 System.arraycopy(a, 0, newArray, 0, Math.min(a.length, newLength)); return newArray; // 转不会原始实际数组对象类型 } /** * A good method of Array copy * @param a * @param newLength * @return */ public static Object goodCopyOf(Object a, int newLength) { Class<?> c = a.getClass(); if(!c.isArray()) return null; Class<?> componentType = c.getComponentType(); // Returns the Class representing the component type of an array. int length = Array.getLength(a); Object newArray = Array.newInstance(componentType, newLength); System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength)); return newArray; }
实例
public static void main(String[] args) { Object object = new Object[10]; if(object.getClass().isArray()) { Object[] objects = (Object[]) object; for(int i=0; i<objects.length; i++){ objects[i] = "Fuck you!"; } for (Object objStr : objects) { if(objStr.getClass() == String.class){ System.out.println(objStr.toString()); } // 或者// System.out.println(objStr); } } public class Test{ public static void main(String[] args) { Object object = new Object[10]; if(object.getClass() == String[].class) { // 条件不成立 Object[] objects = (Object[]) object; for(int i=0; i<objects.length; i++){ objects[i] = "Fuck you!"; } for (Object objStr : objects) {// if(objStr.getClass() == String.class){// System.out.println(objStr.toString());// }// // 或者 System.out.println(objStr); } } } public static void main(String[] args) { Object object = new Object[10]; if(object.getClass() == Object[].class) { // 可以的 Object[] objects = (Object[]) object; for(int i=0; i<objects.length; i++){ objects[i] = "Fuck you!"; } for (Object objStr : objects) {// if(objStr.getClass() == String.class){// System.out.println(objStr.toString());// }// // 或者 System.out.println(objStr); } } }
Java独特的方法调用机制(不太好,容易出错)
public class Test{ public static void main(String[] args) { try { Method out = Test.class.getMethod("out", String.class); out.invoke(new Test(), "OK men and girls"); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } } public void out(String str){ System.out.println(str); }}
0 0
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- 反射机制
- hdu 2680 Choose the best route (dijkstra算法 最短路问题)
- 【Android-008】【Html源文件查看器】
- hdu 2962 Trucking (二分+最短路Spfa)
- 如何在iOS中使用Block
- hdu 1690 Bus System(Dijkstra最短路)
- 反射机制
- hdu 1431 素数回文
- hdu 1395 2^x mod n = 1(暴力题)
- hdu 1102 Constructing Roads (最小生成树)
- hdu 1162 Eddy's picture(最小生成树算法)
- hdu 1875 畅通工程再续
- hdu 1230 火星A+B
- Android 项目(一):网络请求封装(一)
- hdu 1863 畅通工程 (并查集+最小生成树)