反射(三):利用反射來操作類的其它結構

1.操作類的構造方法

Class.newInstance()只能調用無參構造

Class.getDeclaredConstructors能獲取(public protected default private)的構造函數

Class.getConstructors只能獲取public的構造函數

class News {
    public News() {
        System.out.println(0);
    }


    private News(String str) {
        System.out.println(1);

    }
    private News(String str, Double x) {
        System.out.println(2);

    }
    public void print(String str) {
        System.out.println(str);
    }
}

        Class<?> cls = News.class;
        Constructor[] constructors =  cls.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.print(Modifier.toString(constructor.getModifiers()) + " ");
            System.out.print(constructor.getName() );
            Class<?>[] prams =  constructor.getParameterTypes();
            System.out.print("(");
            for (Class cls1 : prams) {
                System.out.print(cls1.getName() + ",");
            }

            if (prams.length > 0) {
                System.out.print("\b");
            }
            System.out.println(");");

            constructor.setAccessible(true);
            if (prams.length == 0) {
                constructor.newInstance();
            } else if (prams.length == 1) {
                constructor.newInstance("1");
            } else {
                constructor.newInstance("1", 1.10);
            }
        }

結果:
public com.mingji.News(java.lang.String,java.lang.Double);
2
public com.mingji.News(java.lang.String);
1
public com.mingji.News();
0

從上可知,我們能獲取構造函數的修飾符,參數,構造方法的名稱,通過constructor並不能newInstance私有構造函數,但是調用constructor.setAccessible(true)就能實現調用

2.操作類的中的方法

interface Message {
    public void print();
}

abstract class Info {
    public abstract void get();

    public void mingji() {}
}

class MessageImpl extends Info implements Message {
    @Override
    public void get() {

    }

    @Override
    public void print() {

    }

    public void set() {}
}

        Method[] methods = MessageImpl.class.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
結果:
public void com.mingji.MessageImpl.get()
public void com.mingji.MessageImpl.print()
public void com.mingji.MessageImpl.set()
public void com.mingji.Info.mingji()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

如果getMethods改爲getDeclaredMethods

結果爲:
public void com.mingji.MessageImpl.get()
public void com.mingji.MessageImpl.print()
public void com.mingji.MessageImpl.set()

可見getDeclaredMethods只有自己的方法,而getMethods可得繼承得來的方法

通過invoke來調用函數

    public String  print(String str) {
        return "echo:"+str;
    }

        Method method = MessageImpl.class.getMethod("print", String.class);
        Object object = method.invoke(MessageImpl.class.newInstance(), "我是誰");
        System.out.println(object);

結果:
echo:我是誰

通過類似配置文件的方式來實例化對象,並對其進行調用

class TestConfig {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class StringUtil {
    public static String initCap(String str) {
        if (null == str) {
            return null;
        }
        return str.substring(0,1).toUpperCase() + str.substring(1);
    }
}

        String ClassName = "com.mingji.TestConfig";
        String propertyName = "name";
        String propertyValue = "fuzhiwei";
        Class<?> cls = Class.forName(ClassName);
        Object insObj = cls.newInstance();
        Field field = cls.getField(propertyName )
        Method method = cls.getMethod("set" + StringUtil.initCap(propertyName), field.getType());
        method.invoke(insObj, propertyValue);

        Method getMethod = cls.getMethod("get" + StringUtil.initCap(propertyName));
        Object returnObj = getMethod.invoke(insObj);
        System.out.println(returnObj);

結果:
fuzhiwei

3.操作類中的成員

interface Message {
    public static final String MSG = "MINGJI";
    String mingjiMsg = "mingjizui";
}

class Self {
    public String mingjiPublic = "mingji public";
    protected String mingjiProtected = "mingji protected";
    String mingjiDefault = "mingji default";
    private String mingjiPrivate = "mingji private";
}

class MessageSelf extends Self implements Message {
    public String msgPublic = "MessageSelf public";
    protected String msgProtected = "MessageSelf protected";
    String msgDefault = "MessageSelf default";
    private String msgPrivate = "MessageSelf private";
    public String mingjiPublic = "mingji public1";
    protected String mingjiProtected = "mingji protected1";
    String mingjiDefault = "mingji default1";
    private String mingjiPrivate = "mingji private1";
}

        Class<?> cls = MessageSelf.class;
        Object insObj = cls.newInstance();
        {
            Field[] fields = cls.getFields();
            for (Field field : fields) {
                System.out.println(field + "value:" + field.get(insObj));

            }
        }
        System.out.println("**********************************");
        {
            Field[] fields = cls.getDeclaredFields();
            for (Field field : fields) {
                System.out.println(field);
            }
        }

結果:
public java.lang.String com.mingji.MessageSelf.msgPublicvalue:MessageSelf public
public java.lang.String com.mingji.MessageSelf.mingjiPublicvalue:mingji public1
public static final java.lang.String com.mingji.Message.MSGvalue:MINGJI
public static final java.lang.String com.mingji.Message.mingjiMsgvalue:mingjizui
public java.lang.String com.mingji.Self.mingjiPublicvalue:mingji public
**********************************
public java.lang.String com.mingji.MessageSelf.msgPublic
protected java.lang.String com.mingji.MessageSelf.msgProtected
java.lang.String com.mingji.MessageSelf.msgDefault
private java.lang.String com.mingji.MessageSelf.msgPrivate
public java.lang.String com.mingji.MessageSelf.mingjiPublic
protected java.lang.String com.mingji.MessageSelf.mingjiProtected
java.lang.String com.mingji.MessageSelf.mingjiDefault
private java.lang.String com.mingji.MessageSelf.mingjiPrivate

從上可知:

1.getFields獲取繼承類的public成員或接口的public成員及自己類的public成員,同時也知道interface的默認限定修飾符爲public

2.getDeclaredFields獲取自己的(public protected default private)成員

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章