反射
来源:互联网 发布:阿里云域名解析 编辑:程序博客网 时间:2024/06/08 07:36
反射
Class
public class ReflectionTest { public static void main(String[] args) { 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 { Class c1 = Class.forName(name); Class superC1 = c1.getSuperclass(); //返回父类 String modifiers = Modifier.toString(c1.getModifiers());//Modifier修饰符工具类 if(modifiers.length() > 0) System.out.print(modifiers + " "); System.out.print("class " + name); if(superC1 != null && superC1 != Object.class) System.out.print(" extends " + superC1.getName()); System.out.print("\n{\n"); printFields(c1); System.out.println(); prinConstructors(c1); System.out.println(); prinMethods(c1); System.out.println("}"); } catch (Exception e) { e.printStackTrace(); } } public static void printFields(Class c1) { //返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 Field[] fields = c1.getDeclaredFields(); for(Field f : fields) { System.out.print(" "); String modifiers = Modifier.toString(f.getModifiers()); //修饰符 Class type = f.getType(); //变量类型 String name = f.getName(); //变量名 if(modifiers.length() > 0) System.out.print(modifiers + " "); System.out.println(type.getSimpleName() + " " + name + ";"); } } public static void prinConstructors(Class c1) { //返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。 Constructor[] constructors = c1.getDeclaredConstructors(); for(Constructor c : constructors) { System.out.print(" "); String modifiers = Modifier.toString(c.getModifiers()); //修饰符 String name = c.getName(); //方法名 if(modifiers.length() > 0) System.out.print(modifiers + " "); System.out.print(name + "("); Class[] paramTypes = c.getParameterTypes(); //显示参数 for(int j = 0; j < paramTypes.length ; j++) { if(j > 0) System.out.print(", "); System.out.print(paramTypes[j].getSimpleName()); } System.out.println(");"); } } public static void prinMethods(Class c1) { //返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法, //包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 Method[] methods = c1.getDeclaredMethods(); for(Method m : methods) { System.out.print(" "); String modifiers = Modifier.toString(m.getModifiers()); //修饰符 Class retType = m.getReturnType(); //返回值 String name = m.getName(); //方法名 if(modifiers.length() > 0) System.out.print(modifiers + " "); System.out.print(retType.getSimpleName() + " " + name + "("); Class[] paramTypes = m.getParameterTypes(); //显示参数 for(int j = 0; j < paramTypes.length; j++) { System.out.print(paramTypes[j].getSimpleName()); if(j > 0 ) System.out.print(", "); } System.out.println(");"); } }}
结果:
Enter class name (e.g java.util.Date):java.lang.Stringpublic final class java.lang.String{ private final char[] value; private int hash; private static final long serialVersionUID; private static final ObjectStreamField[] serialPersistentFields; public static final Comparator CASE_INSENSITIVE_ORDER; public java.lang.String(byte[], int, int); public java.lang.String(byte[], Charset); public java.lang.String(byte[], String); public java.lang.String(byte[], int, int, Charset); public java.lang.String(byte[], int, int, String); java.lang.String(char[], boolean); . . . public boolean equals(Object); public String toString(); public int hashCode(); public int compareTo(String); public volatile int compareTo(Object); public int indexOf(Stringint, ); public int indexOf(String); . . .}
查看任意对象的内部信息
public class ObjectAnalyzer { /** * 标记是否被访问过 */ private ArrayList<Object> visited = new ArrayList<>(); public String toString(Object object) { // 如果为null,就返回一个null字符串 if(object == null) return "null"; // 记录该对象是否被访问过 if(visited.contains(object)) return "..."; // 标记该对象被访问 visited.add(object); // 获取class实例 Class c1 = object.getClass(); // 如果是String的类直接返回String if(c1 == String.class) return (String) object; // 如果是一个数组类型 if(c1.isArray()) { // 获取该数组的数据类型 -> 开始数组 String r = c1.getComponentType() + "[]{"; // 遍历该数组 for(int i = 0; i < Array.getLength(object); i++) { // 如果不是第一个需要输入,(方便查看) if(i>0) r += ","; // 返回指定数组对象中索引组件的值。 Object val = Array.get(object, i); // 判断是否为基本类型,如果不是基本类型还要继续遍历(递归) if(c1.getComponentType().isPrimitive()) { // 如果是基本类型就添加字符串 r += val; } else { // 递归(使用 += 继续拼接字符串) r += toString(val); } } // ->闭合数组字符串 return r+"}"; } // 如果不是数组 // 获取类的名称 String r = c1.getName(); do { // 开始拼接字符串 r += "["; // 获取所有的实例域 Field[] fields = c1.getDeclaredFields(); // 设置所有的实例域都可以访问(由于有的类中的属性字段为private的类型) AccessibleObject.setAccessible(fields, true); // 遍历field for(Field f : fields) { // 判断如果是非静态的属性 if(!Modifier.isStatic(f.getModifiers())) { //如果开头不是 "[" 使用,号隔开,目的是方便查看 if(!r.endsWith("[")) r += ","; //获取名称,并拼接字符串 r += f.getName() + "="; try { // 获取属性的数据类型 Class t = f.getType(); // 获取该属性的数据值 Object val = f.get(object); // 判断是否为基本类型,如果是就拼接,如果不是就再次递归 if(t.isPrimitive()) r += val; else r += toString(val); } catch (Exception e) { e.printStackTrace(); } } } //结束标记 r += "]"; // 获取到超类,一直向上遍历 c1 = c1.getSuperclass(); }while(c1 != null); // 返回最终的字符串 return r; }}
结果:
java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],null,null,null,null,null,null,null},size=3][modCount=3][][]
java.lang.reflect.Arraypublic static Object get(Object array,int index)返回指定数组对象中索引组件的值。array - 数组index - 索引 public static int getLength(Object array)以 int 形式返回指定数组对象的长度。 array - 数组 java.lang.Class<T>public T newInstance()创建此 Class 对象所表示的类的一个新实例。public boolean isPrimitive()判定指定的 Class 对象是否表示一个基本类型。public boolean isArray()判定此 Class 对象是否表示一个数组类。public Class<?> getComponentType()返回表示数组组件类型的 Class。java.lang.reflect.Fieldpublic Object get(Object obj)返回指定对象上此 Field 表示的字段的值。public void set(Object obj, Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值。java.lang.reflect.AccessibleObjectpublic boolean isAccessible()获取此对象的 accessible 标志的值。 public void setAccessible(boolean flag)将此对象的 accessible 标志设置为指示的布尔值。public static void setAccessible(AccessibleObject[] array, boolean flag)使用单一安全性检查(为了提高效率)为一组对象设置 accessible 标志的便捷方法。
使用反射编写泛型数组代码扩展数组长度
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub String[] a = {"Hello","World","Good"}; a = Arrays.copyOf(a, 10); System.out.println(Arrays.toString(a)); String[] b = {"Tom", "Dick", "Harry"}; b = (String[]) goodCopyOf(b, 10); System.out.println(Arrays.toString(b)); String[] c = {"Tom", "Dick", "Harry"}; // String[]数组转换为Object Object obj = c; // 再从Object转换为String[]数组都是可以的 c = (String[]) obj; // java.lang.ClassCastException // 返回的是新建的Object[]数组,这个新建的Object[]数组无法转换为String[]数组 c = (String[]) badCopyOf(c, 10); } public static Object[] badCopyOf(Object[] a,int newLength) { // newArray一开始就是Object[]数组 Object[] newArray = new Object[newLength]; System.arraycopy(a, 0, newArray, 0, Math.min(a.length, newLength)); return newArray; //这是返回的是newArray } public static Object goodCopyOf(Object a, int newLength) { Class c1 = a.getClass(); if(!c1.isArray()) return null; Class componentType = c1.getComponentType(); int length = Array.getLength(a); Object newArray = Array.newInstance(componentType, newLength); System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength)); return newArray; }}
结果:
[Hello, World, Good, null, null, null, null, null, null, null][Tom, Dick, Harry, null, null, null, null, null, null, null]Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; at com.reflection3.Test.main(Test.java:30)
阅读全文
0 0
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- angular(1)创建项目及运行
- Leetcode: 73. Set Matrix Zeroes(Week15, Medium)
- bootstrap页面左侧导航栏 右侧网页
- 文件传输基础——Java IO流
- 导入测试数据test.sql
- 反射
- docker重启后启动失败Failed to start Docker Application Container Engine.
- MyBatis框架学习(2)----MyBatis接口式编程
- JS实现两个datagrid的数据移动
- 捉迷藏
- Java跨平台
- 高性能网络编程(一)----accept建立连接
- 优惠券领取--Java电商
- 数据结构之栈的初始化、创建、入栈、出栈、销毁-c++代码实现