2013-11-16 5 views
0

Пожалуйста, посмотрите на этот сниппет первый:Java Generic инициализации объекта

public MultiThreadManager(Class<T> c) { 
    T[] allJobs = (T[]) Array.newInstance(c , MAX_THREAD_SIZE) ; 
    for (int i = 0 ; i < MAX_THREAD_SIZE ; i ++) { 
     allJobs[i] = (T) new Object(); 
     service.submit(allJobs[i]); 
     getWaitingThreads().add(allJobs[i]); 
    }   
} 

Вот исключение:

Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to slave.JobTemplate 

То, что я пытаюсь сделать:

Конструктор MultiThreadManager должен принять общий тип (скажем Job.java), который реализует Callable. Создайте массив всех этих общих типов данных (Job, java). Инициализируйте его так, чтобы выполнялся конструктор родового типа данных (Job.java) и выполнял их в службе исполнителя.

Пожалуйста, помогите мне определить мою ошибку или предложить лучший способ.

Спасибо заранее

Спасибо вам все, но все немного сложнее: Herez другая информация:

public class Job extends JobTemplate<String> {...details ...} 
public abstract class JobTemplate<T> implements Callable<T> {...details..} 

и, наконец,

MultiThreadManager<Job> threadManager = new MultiThreadManager<Job>(Job.class); 

Опять спасибо :)

ответ

3

Когда вы говорите new Object(), который создает новый объект класса Object. Его динамический тип времени выполнения - Object. Таким образом, листинг до T не будет логически корректным, если только T фактически не является Object.

Что нужно сделать, чтобы создать T, используется отражение, чтобы вызвать соответствующий конструктор на T.

+0

Спасибо Робин. Но вещи немного сложнее :) herez Остальное: –

+0

Робин может у вас проверить мои изменения .... Спасибо –

5

Вам нужно больше отражения, так же, как вам нужно создать массив:

allJobs[i] = c.newInstance(); 

и окружить примерки улова для всех этих надоедливых проверяемых исключений.

Однако я бы предложил использовать new Callable[], потому что нет необходимости вникать в специфику фактического типа работы. Вы также должны рассмотреть дизайн, в котором отражение необязательно: вызывающий объект создает задания вместо передачи в объекте класса. В текущем решении есть ограничение на тип задания, которое должно быть создано только через конструктор по умолчанию.

+0

Отметьте, пожалуйста, проверьте мои изменения ... Спасибо :) –

+0

Большое спасибо. Ваше предложение помогло :) –

2

Робин & Марко показал источник этой проблемы, и у меня есть еще одна вещь, чтобы подчеркнуть вне, от "Effective Java" By Joshua Bloch:

Пункт 25: Предпочитают списки массивам
... массивы и generics имеют очень разные правила типа. Массивы являются ковариантными и овеществленными; дженерики инвариантны и стираются. В качестве результата массивы обеспечивают безопасность типа времени выполнения, но не время компиляции , и наоборот, для дженериков. Вообще говоря, массивы и дженерики плохо смешиваются. Если вы обнаружите, что их микшируете, и , чтобы получить ошибки во время компиляции или предупреждения, ваш первый импульс должен быть , чтобы заменить массивы списками.

Объяснение:

Ковариантное - значит, что, например, массив объектов является супертипом массив Integer. Дженерик invarient, значит, вы не можете бросить List<Integeer> к List<Object>

реифицированных - вся информация, которая существует для массивов во время компиляции также доступен во время выполнения. Дженерики реализуются erasure, что означает, что их ограничения типов применяются только во время компиляции, а затем стираются (он не существует во время выполнения).

Резюмируя:
Смешение массивы с дженериков, скорее всего, вызовет у вас проблемы - попытаться избежать смешивания двух с использованием списков вместо массивов:

public <T> void MultiThreadManager(Class<T> c) 
       throws IllegalAccessException, InstantiationException { 

    List<T> allJobs = new ArrayList<T>(MAX_THREAD_SIZE) ; 
    for (int i = 0; i < MAX_THREAD_SIZE; i++) { 
     allJobs.add(c.newInstance()); 
     service.submit(allJobs.get(i)); 
     getWaitingThreads().add(allJobs.get(i)); 
    } 
} 
+0

Спасибо alfasin ... Я постараюсь реорганизовать –

+0

@AkhilSoni Я добавил пример кода – alfasin

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