Есть ли какой-нибудь способ получить класс для Java или создать экземпляр типа с двойным родом?
Так сказать, у меня есть:
public class Foo<T> {
// Some stuff
}
public interface Factory<T> {
T newInstance();
Class<T> getKlass();
}
И я хочу сделать реализацию Factory для сборки Foo
public class FooFactory<T> implements Factor<Foo<T>> {
private Class<Foo<T>> klass;
public FooFactory(Class<Foo<T>> klass) {
this.klass = klass;
}
public T newInstance() throws Exception {
return klass.newInstance();
}
public Class<Foo<T>> getKlass() {
return klass;
}
}
Два вопроса:
- Могу ли я получить Класс
>, если у меня есть только Класс ? К сожалению, Foo является закрытым классом, и поэтому единственный код, который имеет всю картину (т.е. знает, что будет с T), не может знать о Foo и, следовательно, не может дать мне Class >. - Есть ли лучший способ, которым я мог бы пойти об этом?
Спасибо!
PS Для тех, кто просит более подробно, здесь мы идем. Вся история в том, что Foo и FooFactory будут частными классами во внешнем классе. Foo широко используется во внешнем классе, и чтобы избежать ложной сборки мусора, я бы хотел использовать ObjectPool для создания экземпляров экземпляров Foo, а не обновлять их и постоянно собирать мусор. Однако, чтобы использовать мой ObjectPool, мне нужен Factory
public class Outer<T> {
private class Foo<T> { ... }
private class FooFactory<T> {...}
private ObjectPool<Foo<T>> fooPool;
...
}
2 ответа
Существуют способы создания информации о типе для Class<Foo<T>>
но чтобы делать то, что вы хотите, вам просто нужно подавить все предупреждения FooFactory
,
Во время выполнения Java использует Object
во всех местах, где вы написали T
, так что вы можете просто создать экземпляр Foo<Object>
или же Foo.class
, они одинаковые. Это называется стиранием типа.
Обобщения являются лишь подсказкой для компилятора. Поскольку ваш API гарантирует, что весь код использует FooFactory
будет соблюдать тип T
Вы можете подавить предупреждения и использовать соответствующие приведения, и это будет работать.
Примечание. Если вы хотите сохранить информацию о типе, выполните ParameterizedType
интерфейс
Есть только один Foo
объект класса, который равен Foo.class
, Хотя ты можешь написать Class<Foo<whatever>>
это обманчиво, так как все равно Foo
объект класса. Конечно нужно Class<Foo<T>>
уметь звонить newInstance()
и получить Foo<T>
, Так что обойти тот факт, что вам нужно Class<Foo<T>>
и это Foo.class
имеет тип Class<Foo>
Вы просто делаете кастинг:
public FooFactory() {
this.klass = (Class<Foo<T>>)(Class<?>)Foo.class;
}
Обратите внимание, что нам не нужно Class<T>
вообще, потому что вам не нужно знать T
создать Foo<T>
,