反射

来源:互联网 发布:阿里云域名解析 编辑:程序博客网 时间: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)

这里写图片描述

原创粉丝点击