当前位置: 首页 > 知识库问答 >
问题:

Java抽象泛型方法,使用具体类型实现通配符

阙俊友
2023-03-14

在java中,是否可以使用通配符定义抽象方法,但在实现中使用具体类型

eg:

在这样的抽象类中定义抽象方法

public abstract class AbstractAuthorizer {
    abstract protected <T extends User> void authorize( T user );
}

实现如下抽象方法,其中CorporateServer扩展了用户:

public class CorporateAuthorizer extends AbstractAuthorizer {

    @Override
    protected <CorporateUser> void authorize(CorporateUser user){
    }
}

共有2个答案

於子晋
2023-03-14

抽象类正在声明一个方法,该方法将授权任何

一些选项:

>

  • 生成抽象类。

    abstract class AbstractAuthorizer<T extends User> {
        protected abstract void authorize(T user);
    }
    
    class CorporateAuthorizer extends AbstractAuthorizer<CorporateUser> {
        protected void authorize(final CorporateUser user) {
            // Do authorization.
        }
    }
    

    让分机执行必要的检查。大致如下(使用AbstractAuthorizer定义如下):

    class CorporateAuthorizer extends AbstractAuthorizer {
        protected <T extends User> void authorize(final T user) {
            if (!(user instanceof CorporateUser)) {
                throw new UnsupportedOperationException("CorporateAuthorizer can only authorize 'CorporateUser' users");
            }
            // Do authorization.
        }
    }
    

    如果你选择后者,我强烈建议你增加一个抽象布尔支持(User)哪个执行上述instanceof检查,以便它可以用作:

    boolean checkAuth(final User user) {
        boolean authorized = false;
        for (final AbstractAuthorizer authorizer : authorizers) {
            if (authorizer.supports(user)) {
                authorizer.authorize(user);
                authorised = true;
                // break; if only a single authorizer's check is required.
            }
        }
        return authorised;
    }
    

    我还会注意到的方法

    abstract class AbstractAuthorizer {
        abstract boolean supports(User user);
    
        abstract <T extends User> T authorize(T user);
    }
    

  • 壤驷深
    2023-03-14

    不,你不能直接做你要求的。然而,你可以得到同样的效果。

    当你创建泛型时,你向用户promise:这将适用于任何满足泛型边界的类型。所以通过在子类中选择特定的类型,你就违反了这条规则。然而,如果你正确定义了超类,那么你可以在满足类型检查器的同时获得你想要的行为。不要让函数泛型,让类泛型,然后当你子类时,你可以选择它适用于哪种类型。

    public abstract class AbstractAuthorizer<T extends User> {
        abstract protected void authorize( T user );
    }
    
    public class CorporateAuthorizer extends AbstractAuthorizer<CorporateUser> {
        @Override
        protected void authorize(CorporateUser user) {}
    }
    
     类似资料:
    • 它是关于java中具有两种泛型类型(一种用于返回类型,另一种用于形式参数)的泛型方法以及如何实现它。我想我在图片中缺少一些东西来让它工作。 事情是这样的... 这是工作 : 这不起作用: java编译器告诉我: 好吧,就是这样。提前感谢大家!希望它能在未来帮助别人! P、 D:这不是枚举类型的问题。它发生在类和层次结构之间。所以别怪Enum了,我试过了,但没用。 对于泛型参数 我们可以做一个一般规

    • 例如,我有以下接口 实现此接口的抽象类 以及具体实施 我想建议所有将转换为任何内容的方法。我创建了以下方面 这是行不通的。Spring不会为类创建代理。然而,如果我从抽象类重写方法,它将开始工作,Spring成功地为创建代理,并执行所有需要的逻辑。 为什么会发生这种情况?有没有办法定义切入点,这样我就不需要重写方法?

    • 在JLS 8第8.4.8.1节中,有一条声明: 在某些参数化下,泛型超类C中的具体方法可以与该类中的抽象方法具有相同的签名。在这种情况下,具体方法是继承的,而抽象方法不是。然后应将继承的方法视为覆盖其来自C的抽象对等体。 有人能为泛型类提供这种参数化的例子吗?我不能。

    • 我不熟悉泛型。我有一个抽象类(1)和一个抽象方法。我有另一个抽象类(2)和一些抽象方法,我希望在一些DTO(3,4)中共享这些抽象方法。我想要一个(1)的具体扩展来处理任何扩展(2)的东西。 1. 扩展StagingError的两个类:3.

    • 编译时,此代码将产生以下+错误: 问题是访问中的类型T与列表中的T不相同。如何修复此编译问题?

    • 问题内容: 我了解编译器使用目标类型来确定使通用方法调用适用的类型参数。例如,在以下语句中: 其中的签名中具有类型参数 在这种情况下,推断出的类型参数是。 现在考虑以下几点: 在这种情况下,推断的类型是什么?是吗 还是因为通配符告诉编译器任何类型都是可能的? 问题答案: 通配符的每种用法都有与之关联的不同类型。(通常,JLS将此称为“新鲜类型”。)例如,这就是这样的编译器错误的工作方式: 因为在这