2016-04-13 5 views
0

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

BaseDtoUtil.mapToDto(map, OcrImageDocDto.class); //OcrImageDocDto extends DtoUtils 

//This method is in class BaseDtoUtil 
public static <T> List<T> mapToDto(Map<String, Object> map, Class<? extends DtoUtils> klass) throws SparkSQLException{ 
     T obj = (T)klass.newInstance(); 
     //return a list of these 
} 

Так что я думаю, есть два вопроса, у меня есть:

  1. первых, почему это жалуются, когда я прохожу в OcrImageDocDto.class, когда переменная, определенная для вызова метода является любой класс? (Я изначально имел это как (Class<?>). Это не означает какое-либо значение класса? Очевидно, я ошибаюсь, но не уверен, что это значит.
  2. Второй вопрос: если я отправляю значение класса, я действительно могу получить это экземпляр и возвращает значение типа обратно? <T> List<T>? Если я не ошибаюсь, я считаю, что общие переменный <T> List<T> используются для конкретизации объекта. Но что они делают, если это статический метод?

Я немного потеряно и, может быть, я понимаю, что дженерики ошибочны ... Поэтому, если кто-то может очистить эти два, я думаю, что это поможет!

+2

Вам нужно будет использовать '' вместо того, чтобы просто '', и 'Класс '. –

+0

Также интересует: https://docs.oracle.com/javase/tutorial/java/generics/erasure.html –

+1

рассмотреть возможность изменения подписи на public public Список mapToDto (Карта map, Class klass) '- чтобы метод знал« Список », какой тип он должен вернуть. –

ответ

2

Вопрос 1:

public static <T> List<T> mapToDto(
    Map<String, Object> map, 
    Class<? extends DtoUtils> klass) throws SparkSQLException{ 
    T obj = (T)klass.newInstance(); 
    ... 

Вы не знаете, что klass.newInstance() может быть приведён к T - все, что вы знаете, что это экземпляр DtoUtils (или подкласс).

Таким образом, вы можете либо изменить, чтобы использовать:

DtoUtils obj = klass.newInstance(); 

или ограничить T расширить DtoUtils:

public static <T extends DtoUtils> List<T> mapToDto(
    Map<String, Object> map, 
    Class<? extends T> klass) throws SparkSQLException{ 
    T obj = klass.newInstance(); 
    ... 

Вопрос 2:

Да, потому что у вас есть реальный экземпляр класса. Вы не сможете создать экземпляр без этого (или какой-либо другой объект, который может предоставить экземпляры T) из-за стирания типа.

Это не будет работать:

public static <T extends DtoUtils> List<T> mapToDto(
    Map<String, Object> map) throws SparkSQLException{ 
    T obj = new T(); // Compiler error. 

Что-то вроде следующих работ просто отлично:

T obj = klass.newInstance(); 
List<T> list = new ArrayList<>(); 
list.add(obj); 
return list; 
+0

Ahhhh Я люблю ответ 1. Это имеет большой смысл.Также вы можете объяснить, как он знает, что такое T? основано ли это на том, что мы устанавливаем на противоположной стороне «=» или как оно знает, как решить, что такое значение T? –

+0

Я понимаю это сейчас. Я вижу, что это то, для чего объект установлен для определения T. Также мне нравится комментарий, который выше о том, как вызвать этот метод ... public static T mapToDto (Карта map, Class класс) бросает SparkSQLException; Это позволяет мне заставлять их передавать то же значение, что и я. Энди, пожалуйста, измените класс и измените его на класс , и я отмечу это как ответ! Благодаря!! –

+0

'T' никогда не определяется. Как известно, это нечто, что расширяет «DtoUtils», поэтому мы знаем, что мы можем ссылаться на любой из методов DtoUtils на его экземплярах. –

Смежные вопросы