代码之家  ›  专栏  ›  技术社区  ›  Leviand

泛型对象参数的类型问题

  •  1
  • Leviand  · 技术社区  · 6 年前

    我有一个抽象类,

    public abstract class WebserviceIntegration {
        //...
    }
    

    public class Manager extends WebserviceIntegration {
        //...
    }
    

    现在我已经构建了一个类,它和抽象类一样具有泛型参数 F

    public class NewUserWindow<T, F extends WebserviceIntegration> extends Window {
    
        public NewUserWindow(T objOne, F objTwo) {
            //...
            saveConnectedBean(objTwo); //no problems here
        }
    
        public void saveConnectedBean(F bean) throws MyException{
            //...
        }
    }
    

    如果我创建一个新窗口,一切都很好 NewUserWindow<?, Manager> window = new NewUserWindow<>(new OtherClass(), new Manager());

    现在我要做的是保存一个 新的 Manager 在构造器内部:

    public NewUserWindow(T objOne, F objTwo) {
            //...
    
            Manager manager = new Manager();
            //... setting manager stuff
    
            saveConnectedBean(manager); //does not compile
     }
    

    编译器现在阻止我这么说了 saveConnectedBean(F) in NewUserWindow cannot be applied to (my.package.path.Manager) 如果我把它换成

    saveConnectedBean((F)manager);
    

    它编译了,但警告我强制转换未选中。

    1. 在第一种情况下,为什么编译器不知道 班级正在扩大 WebserviceIntegration ,使其与 F级 上课?

    2. manager instanceof F ,那我该怎么办?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Leviand    6 年前

    这不是很清楚,但根据您的问题,我认为失败的代码位于泛型类的构造函数中。

    F 声明为泛型类内部,编译器不知道 F级 . 别忘了泛型只是编译工件。
    Manager 变量,例如:

    Manager manager = new Manager();
    

    NewUserWindow<?, OtherSubClass> window = ... 它会破坏类型安全。

    2) 避免 instanceof

    作为替代,你应该通过考试 经理 从通用实例的客户端,例如:

    Manager manager = new Manager();
    NewUserWindow<?, Manager> newUserWindow = new NewUserWindow<>(new ..., manager);
    newUserWindow.saveConnectedBean(manager);
    

    根据您的评论:

    假设我无法找到解决方案2,还有其他方法吗 安全铸造?

    你可以这样做 NewUserWindow F级 .

    public abstract class NewUserWindow<T, F extends WebserviceIntegration> extends Window {
    
        public NewUserWindow(T objOne, F objTwo) {
    
            F f = createF();
            saveConnectedBean(f);
        }
    
        public abstract F createF();
    
        public void saveConnectedBean(F bean) throws MyException{
            //...
        }
    }
    

    并实施如下:

    public ManagerUserWindow extends NewUserWindow<T, Manager> extends Window {
    
        public Manager createF(){
           return new Manager();
        }
    
    }
    
        2
  •  1
  •   Maxim    6 年前

    save 方法 WebserviceIntegration

    public static abstract class WebserviceIntegration {
        public abstract void save();
    }
    

    Web服务集成

    public static class Manager extends WebserviceIntegration {
        @Override
        public void save() { // saving Manager here }
    }
    

    所以呢 saveConnectedBean Web服务集成

    public void saveConnectedBean(WebserviceIntegration bean) { }
    

    Web服务集成 功能。


    或者,可以引入新的方法类型参数

    public <B extends WebserviceIntegration> void saveConnectedBean(B bean) { }
    

    保存的ConnectedBean 仅限于使用中的方法实现