反射机制
2015-10-12 14:20
465 查看
反射
能够分析“类”(不是对象)能力的程序称为反射(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.class c = Enum.class c = void.class c = boolean.class c = double.class c = float.class c = Float.class c = new Float(3.4F).getClass c = 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是单进程方式,所以“实现接口”不算继承方法,只算一种多态性质。 Sy 4000 stem.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); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统