繁体   English   中英

具有上限的Java泛型

[英]Java generics with upper bound

说我有以下示例应用程序,我正在使用Java 8。

我的以下课程有一个子课程:

public class GrantedAuthority { }
public class GrantedAuthoritySubClass extends GrantedAuthority { }

下课是棘手的部分:

public class UserDetails {

    Collection<? extends GrantedAuthority> authorities;

    public Collection<? extends GrantedAuthority> getAuthorities(){
        return authorities;
    }
}

我的主要方法:

public class Main {

    public static void main(String[] args) {

        UserDetails u = new UserDetails();
        List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
        list.add(new GrantedAuthoritySubClass());
        u.getAuthorities().addAll(list);
    }
}

运行此命令时,出现以下错误:

错误:( java.util.List<GrantedAuthority> )Java:不兼容的类型: java.util.List<GrantedAuthority>无法转换为java.util.Collection<? extends capture#1 of ? extends GrantedAuthority> java.util.Collection<? extends capture#1 of ? extends GrantedAuthority>

我的问题是,如何将GrantedAuthoritySubClass对象的集合传递给u.getAuthorities()返回的集合。 我无法弄清楚,尝试过的各种方法都有很多编译错误。

根据PECS规则,您的authorities集合是元素的producer者(因为它使用了extends)。 这意味着该集合只能“产生”或“输出” GrantedAuthority对象或其子类。 这也意味着您无法将任何东西放入集合中,因为您不知道集合的实际类型。

如果使用super ,则可以将对象放在此处(但无法将它们取出),但是我怀疑通配符是完全不必要的。

您无法编译,因为您不知道获得哪种集合。

您需要将签名更改为

Collection<? super GrantedAuthority> getAuthorities()

这说明了问题(c) Andrey Tyukin 在此处输入图片说明

您尝试使用通配符过于精确(并以这种方式进入泛型。)

基本上,尽量避免使用通配符,并尽可能使用自然继承。 在您的示例中,如下更改您的UserDetails:

public class UserDetails {
    Collection<GrantedAuthority> authorities;

    public Collection<GrantedAuthority> getAuthorities(){
        return authorities;
    }
}

...一切都会好的。 特别是,随着自然继承的加入,您可以添加GrantedAuthoritySubClass的实例。

因为UserDetails是Spring安全性的接口,所以您不能更改方法定义。 您不能在您的方法中添加GrantedAuthority 但是,在实现中,您可以重写getAuthorities以返回与接口定义匹配的集合:

public class UserDetailsImpl implements UserDetails {

    private Collection<GrantedAuthority> authorities = new  ArrayList<>();

    @Override
    public Collection<GrantedAuthority> getAuthorities() {
        return authorities;
    }
}

现在您可以像这样使用它:

UserDetailsImpl u = new UserDetailsImpl();
u.getAuthorities().add(new GrantedAuthority());

也可以使用您自己的GrantedAuthority类型,如下所示:

public class MyGrantedAuthority extends GrantedAuthority{

}

public class UserDetailsImpl implements UserDetails {

    private Collection<MyGrantedAuthority> authorities = new  ArrayList<>();

    @Override
    public Collection<MyGrantedAuthority> getAuthorities() {
        return authorities;
    }
}


UserDetailsImpl u = new UserDetailsImpl();
u.getAuthorities().add(new MyGrantedAuthority());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM