Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Generics - как избавиться от Cast


Автор: Kizja 25.4.2010, 14:27
Привет, не могу избавится от явного приведения типа в следующем примере, хотя думаю, что в данном случае это возможно:

Код

public class GerericTest {
    
    public static void main(String[] args) throws Exception {
        new GerericTest().test();
    }
    
    public void test() throws Exception {
        ClassInterfaceA genericA = (ClassInterfaceA) init(EnumA.TEST); // TODO: remove cast
        ClassInterfaceB genericB = (ClassInterfaceB) init(EnumB.TEST); // TODO: remove cast
        
        genericA.sayHelloA();
        genericB.sayHelloB();
    }
    
    private <T extends EnumInterface<? extends ClassInterface>> 
            ClassInterface init(T value) throws Exception {
        return value.getClassInterface().newInstance();
    }
}


Код

public interface ClassInterface {

}


Код

public interface ClassInterfaceA extends ClassInterface {
    public void sayHelloA();
}


Код

public interface ClassInterfaceB extends ClassInterface {
    public void sayHelloB();
}


Код

public class ClassA implements ClassInterfaceA {
    @Override
    public void sayHelloA() {
        System.out.println("Hello: " + this.getClass().getName());
    }
}


Код

public class ClassB implements ClassInterfaceB {
    @Override
    public void sayHelloB() {
        System.out.println("Hello: " + this.getClass().getName());
    }
}


Код

public interface EnumInterface<T extends ClassInterface> {
    public Class<? extends ClassInterface> getClassInterface();
}


Код

public enum EnumA implements EnumInterface<ClassInterfaceA> {
    TEST(ClassA.class);
    
    private Class<? extends ClassInterfaceA> clazz;

    private EnumA(Class<? extends ClassInterfaceA> clazz) {
        this.clazz = clazz;
    }
    
    @Override
    public Class<? extends ClassInterfaceA> getClassInterface() {
        return clazz;
    }
}


Код

public enum EnumB implements EnumInterface<ClassInterfaceB> {
    TEST(ClassB.class);
    
    private Class<? extends ClassInterfaceB> clazz;
    
    private EnumB(Class<? extends ClassInterfaceB> clazz) {
        this.clazz = clazz;
    }

    @Override
    public Class<? extends ClassInterfaceB> getClassInterface() {
        return clazz;
    }
}


Поскольку EnumA и EnumB имеют поля с конкретными интерфейсами ClassInterfaceA и ClassInterfaceB, а не общий интерфейс ClassInterface, то думаю, что можно изменить данный пример так, чтобы он возвращал то, что надо без использования каста...

Кто знает как сделать ?

Автор: Joss 25.4.2010, 17:10
Навскидку:
Код

public class GerericTest {
    private <T,U extends EnumInterface<T extends ClassInterface>> T init(U value) throws Exception {
        return value.getClassInterface().newInstance();
    }
}


Компилятора нет под рукой и проверить не получилось. :(

Автор: Kizja 25.4.2010, 22:32
Joss, Данный вариант, к сожалению, не подходит... может вооружившись компилятором что-нибудь могли бы ещё посоветовать ? smile

Автор: Kircul 26.4.2010, 10:11
Попробуй так 
Код

public interface EnumInterface<T extends ClassInterface> {
    public Class<? extends T> getClassInterface();
}

и 
Код

private <T extends ClassInterface> T init(EnumInterface<T> value) throws Exception {
        return value.getClassInterface().newInstance();
}

Автор: Kizja 26.4.2010, 12:23
Kircul

Супер, с твоим вариантом всё работает как надо...

Спасибо!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)