簡體   English   中英

在Java中使用反射來設置方法的參數

[英]Using reflection in Java to set a method's parameters

我正在嘗試實現一些近似的方法:

public class MyClass<E>
{
    protected MyClass(Object[] variables)
    {
        //init
    }

    public MyClass(Comparator<? super E> comp, Object[] variables)
    {
        //init
    }

    public static <K extends Comparable<? super K>, T extends MyClass<K>> 
         T construct(T example, Object[] variables)
    {
        return new T(variables);
    }
}

其中Object []變量不是實際代碼,而是占位符(無論構造的實際參數是什么)。

我的問題就在這里。 我已經看到了無數個示例,無論有無反射,當T的構造函數的參數提前已知並且可以在構造的參數中指定時,該如何做。 但是,即使T的構造函數的參數未知,我也希望能夠做到這一點。 有沒有辦法做到這一點?

只要解決方案有效,我都不在乎該解決方案是否使用反射,但是反射似乎是最可能的選擇。

我對整體反思還很陌生,因此如果這個問題很基本,我深表歉意。

編輯:由於反饋,沒有辦法動態設置construct()的參數,我想稍微改變一下問題。

假定受保護的構造函數具有構造類所需的參數,如果我使用vararg (public static <K extends Comparable<? super K>, T extends MyClass<K>> T construct(T example, Object... variables))確保傳遞給變量的參數與構造函數所需的參數匹配的最佳方法是什么? 我曾希望動態地執行此操作,因為這樣編譯器本身可以避免此類問題,但是如果沒有這種可能性,我會尋求最佳的替代解決方案。

編輯:為了澄清,這是我的實際目標:我想MyClass的能夠接受一個參數,E,擴展相當任何參數,但有一個比較在過去,我可以簡單地通過構造實現第二個目標,但為了。為了讓E在第二種情況下對任何選項都開放,我必須對所有選項都保持開放。 為了解決這個問題,我使通用構造函數受到保護,並制作了一個公共靜態方法來強制Comparable實現並充當偽構造函數,返回類型為MyClass,其中K是Comparable。 但是,這會在另一個類擴展MyClass時引起問題。 如果我事先知道繼承的類將具有與MyClass相同的參數,那么我可以簡單地隱藏該方法並相應地更改返回類型。 但是,如果我想讓子類具有不同的參數,那么我已經更改了方法的簽名,並且不再可以使用它來隱藏前一個方法,這意味着子類不僅可以返回自身的實例,還可以返回一個實例。其父實例完全不同。 這是我想避免的。

這可能有效,但我不建議這樣做。 請注意,要使該example正常工作, variables所有成員都不得為null

public static <K extends Comparable<? super K>, T extends MyClass<K>> 
     T construct(T example, Object[] variables) throws 
                 NoSuchMethodException,
                 SecurityException,
                 InstantiationException,
                 IllegalAccessException,
                 IllegalArgumentException,
                 InvocationTargetException 
{
    Objects.requireNotNull(example);

    Class<?>[] argTypes = new Class<?>[variables.length];
    for ( int i = 0; i < variables.length; ++i)
    {
        // This will NPE if variables[i] is null
        argTypes[i] = variables[i].getClass();
    }

    // This will throw, if constructor is not defined
    Constructor<?> constructor = example.getClass().getConstructor(argTypes);

    return (T) constructor.newInstance(variables);
}

通常,您正在執行的操作可以通過創建一個創建特定類實例的Factory接口來實現。

我認為您不需要反思。 您只需要簡化所需的內容,並使用Java和泛型的功能來滿足您的需求。 這是根據您的第三個編輯的示例:

class MyClass<E> {
    private Comparator<MyClass<E>> comparator;

    public MyClass(List<Object> params, Comparator<MyClass<E>> comparator) {
        //init
        this.comparator = comparator;
    }

}
class  MyClassExtension extends MyClass<Integer> {

    public MyClassExtension(List<Object> params, Comparator<MyClass<java.lang.Integer>> comparator) {
        super(params, comparator);
    }
}
class  MyClassExtension2<E> extends MyClass<E> {

    public MyClassExtension2(List<Object> params, Comparator<MyClass<E>> comparator) {
        super(params, comparator);
    }
}

我想我可能已經實現了一個潛在的解決方案,盡管我希望獲得有關其可行性的反饋。

public class MyClass<E>
{
    public MyClass(Comparable<? super E> example, E example2, Object[] variables) 
      throws IllegalArgumentException
    {
        if(!example.getClass().equals(example2.getClass())
        {
             throw new IllegalArgumentException();
        }
        //init
    }

    public MyClass(Comparator<? super E> comp, Object[] variables)
    {
        //init
    }
}

這個想法是,if語句強制example與通用E屬於同一類,而example作為參數的存在強制該類實現Comparable。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM