2012-01-12 4 views
2

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

public class Fancy { 

static public <TypeToFind> TypeToFind createInSomeCase() { 
    // any type of logic with TypeToFind "class" generic will do, I just want to reference it. 

    // the below code is invalid, I could also declare a variable, but can't always create an instance to get the class 
    if (TypeToFind.getClass().equals(Something.class)) { 
    return TypeToFind.getInstance(); 
    } 
} 


} 

... так позже я мог бы сделать:

TheResultIsTheParameter t = Fancy.createInSomeCase(); 

... вместо

TheResultIsAParameter t = Fancy.createInSomeCase(TheResultIsAParameter.class); 

... или

TheResultIsAParameter t = Fancy.createInSomeCase(t); 

Могу ли я сделать это слишком сложно?

+1

Возможный дубликат [Создание экземпляра родового класса в Java] (http://stackoverflow.com/questions/1090458/instantiating-a-generic-class-in-java) –

+0

@JarrodRoberson Аналогичные проблемы, но не тот же ответ , Пытаясь добиться чего-то другого, и, таким образом, ответ становится другим. +1 все равно - дает больше информации – cgp

ответ

6

Вы не можете этого сделать, потому что дженерики теряются во время выполнения (из-за type erasure). Вы должны передать параметр Class<?>

1

Ну, вы требуете somethink, что логично, unfortunattelly дженериков в Java являются лишь синтаксический сахар для отражения.

List<MyClass> list; 
(...) 
MyClass my = list.get(0); 

будет компилировать

MyClass my = (MyClass) list.get(0); 

и это то, что вы увидите в байткод.

Более того, используя отражение или отливку в нетипизированный список, вы можете поместить любой объект в list, и в обоих кодах вы получите ClassCastException.

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

1

Пока вы не пытаетесь и статически (во время компиляции) ссылки на какой-либо конкретный класс, ничто не мешает вам делать что-то вроде этого:

public class GenericsTest { 
    @Test 
    public void testMe() { 
     GenericsTest test = new GenericsTest(); 
     System.out.println(test.get("Hello").getClass()); 
    } 

    public GenericsTest() { 
     super(); 
    } 

    public <T extends Object> T get(T entity) { 
     return newInstanceForClass((Class<T>)entity.getClass()); 
    } 

    public <T extends Object> T newInstanceForClass(Class<T> clazz) { 
     try { 
     return clazz.newInstance(); 
     } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
     } 
    } 
} 

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

+1

Предполагается, что вы готовы потребовать от пользователя передать экземпляр объекта, который им интересен для создания экземпляра (который я не думаю, что хочет OP), и что вы 'больше интересуется фактическим типом времени выполнения этого объекта, чем в типе времени компиляции, определенном в коде. – StriplingWarrior

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