Получение конструктора из Java класса, который будет вызываться для типов аргументов, не требуя точного соответствия аргумента и типа параметра - PullRequest
2 голосов
/ 27 февраля 2020

Есть ли способ в Java (или в Java библиотеке) получить Constructor из Class, который будет вызываться для заданных аргументов / типов аргументов (не требующих точного аргумента и типа параметра совпадения, вместо этого включая супертипы)?

т.е. я знаю о Class#getConstructor(Class<?>), но это возвращает только точные совпадения.

например, следующий код выдает NoSuchMethodException, тогда как я хочу получить Constructor для A(CharSequence), поскольку это то, что было бы вызвано, если бы я запустился, например, A(""):

public class A {

    public A(Object o) {}
    public A(CharSequence cs) {}

    public static void main(String[] args) throws Exception {
        Constructor c = A.class.getConstructor(String.class);
        c.newInstance("");
    }
}

Я полагаю, что такой метод также потенциально может вызвать исключение, указывающее, что несколько конструкторов совпадают, поэтому он не может выбирать без указания типов аргументов c (как при явном приведении).

Я также хотел бы найти эту функцию для Method s.

Спасибо.

1 Ответ

4 голосов
/ 28 февраля 2020

Вы можете использовать java.beans.Expression.

Чтобы продемонстрировать поведение:

public class A {
    public A(Appendable o) { System.out.println("A(Appendable)");}
    public A(CharSequence cs) { System.out.println("A(CharSequence)");}

    public static void main(String[] args) throws Exception {
        // calls A(CharSequence)
        A a1 = (A)new Expression(A.class, "new", new Object[]{ "string" }).getValue();
        // calls A(Appendable)
        A a2 = (A)new Expression(A.class, "new", new Object[]{ System.out }).getValue();
        // ambiguous, throws exception
        A a3 = (A)new Expression(
            A.class, "new", new Object[]{ new StringBuilder() }).getValue();
    }
}

Обратите внимание, что текущая версия не указывает на то, что проблема является неоднозначной в исключительном случае; его нельзя отличить от ситуации, когда совпадения не были найдены.

Фундаментальное ограничение состоит в том, что невозможно решить эту двусмысленность, поскольку нельзя предварительно выбрать метод или конструктор. Вам придется прибегнуть к низкоуровневому отражению с его требованием для точного соответствия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...