Отражение Java: Что содержит мой Набор?

Самая важная вещь состоит в том, чтобы всегда быть последовательной в том, когда Вы выходите. Случайной двойной очисткой является Ламе, и не очистка опасна.

Для SQL, просто удостоверьтесь, что Ваши поддержки библиотеки доступа к базе данных связывают переменные, который автоматически выходит из значений. Любой, кто вручную связывает ввод данных пользователем на строки SQL, должен знать лучше.

Для HTML, я предпочитаю выходить в прошлый момент. При уничтожении ввода данных пользователем Вы никогда не можете возвращать его, и если они делают ошибку, они могут отредактировать и зафиксировать позже. При уничтожении их исходного входа он пошел навсегда.

5
задан niklassaers 19 November 2009 в 16:25
поделиться

5 ответов

Method.getGenericParameterTypes();

возвращает массив типов, которые принимает параметр. Оттуда сложность возрастает экспоненциально.

В вашем конкретном случае это сработает:

    Method m = Something.class.getMethod("setCollection", Collection.class);
    Class<?> parameter = (Class<?>) ((ParameterizedType) m.getGenericParameterTypes()[0]).getActualTypeArguments()[0];

Но есть много потенциальных ошибок, в зависимости от того, как параметр был объявлен. Если это просто, как в вашем примере, отлично. Если нет, то необходимо учитывать множество типов как в методе getGenericParameterTypes (), так и в методе getActualTypeArguments (). Он очень быстро становится очень волосатым и уродливым.

9
ответ дан 13 December 2019 в 05:37
поделиться

Я бы подумал о переносе методов setCollection в их собственные классы, а затем сделал бы что-то подобное (вы можете изменить это, чтобы создать всю коллекцию сразу, а не делать это как элемент в time).

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

public class Main 
{
    public static void main(String[] args) 
    {
        List<Car> car;
        List<Bar> bar;

        car = new ArrayList<Car>();
        bar = new ArrayList<Bar>();
        init(car, new CarCreator());
        init(bar, new BarCreator());
    }

    private static <T> void init(final List<T>    list,
                                 final Creator<T> creator)
    { 
        for(int i = 0; i < 10; i++)
        {
            final T instance;

            instance = creator.newInstance(i);
            list.add(instance);
        }
    }
}

interface Foo
{    
}

class Bar implements Foo 
{ 
}

class Car implements Foo 
{ 
}

interface Creator<T>
{
    T newInstance(int i);
}

class BarCreator
    implements Creator<Bar>
{
    public Bar newInstance(final int i)
    {
        return (new Bar());
    }
}

class CarCreator
    implements Creator<Car>
{
    public Car newInstance(final int i)
    {
        return (new Car());
    }
}
2
ответ дан 13 December 2019 в 05:37
поделиться

Java реализует универсальные шаблоны со стиранием типа. Компилятор использует эту информацию о типе только для проверки безопасности, байтовый код не содержит информации об общих типах. Следовательно, среда выполнения также не знает об этом, поэтому вы не можете получить его с помощью отражения.

Вы можете найти дополнительную информацию здесь .

Обновление :

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

public <T> String doSomething(T first, int second) {
    return first.toString();
}

В байтовом коде он будет иметь следующую сигнатуру (обратите внимание на тип T):

<T:Ljava/lang/Object;>(TT;I)Ljava/lang/String

Итак, то, что я сказал выше, верно только за этим исключением.

1
ответ дан 13 December 2019 в 05:37
поделиться

Как уже объяснил Candiru, «Тип коллекции» стирается, во время выполнения это не что иное, как Коллекция типов объектов.

Если вам разрешено немного изменить подпись сообщения в вашем подклассы к

public void setCollection(Collection<T> aCollection, Class<T> elementType);

, тогда вы можете передать второй параметр, который содержит информацию о 'Типе Коллекции', использование будет примерно таким:

public void setCollection(Collection<MyClass> myClassCollection, 
                          Class<MyClass> clazz);

и использовать его:

Collection<MyClass> myClassCollection = new ArrayList<MyClassCollection>();
setCollection(myClassCollection, MyClass.class);

Но с другой стороны - обычно вы этого не делаете об этом нужно позаботиться, потому что тип стирается во время выполнения, и вы можете поместить любой объект в параметризованную коллекцию, если компилятор не уловит вас;)

0
ответ дан 13 December 2019 в 05:37
поделиться

Вы, кажется, уже знаете сеттер. Мне кажется, что в этом случае MyClass и OtherClass (не коллекция, а элементы) имеют что-то похожее на интерфейс. В этом случае вам действительно не нужно знать точный тип.

0
ответ дан 13 December 2019 в 05:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: