为了账号安全,请及时绑定邮箱和手机立即绑定

如何使方法返回类型为泛型?

如何使方法返回类型为泛型?

慕桂英3389331 2019-07-04 10:17:33
如何使方法返回类型为泛型?考虑一下这个例子(OOP书籍中的典型例子):我有一个Animal类,其中每个Animal可以有很多朋友。和子类,如Dog, Duck, Mouse等等,它添加了一些特定的行为,如bark(), quack()等。这是Animal班级:public class Animal {     private Map<String,Animal> friends = new HashMap<>();     public void addFriend(String name, Animal animal){         friends.put(name,animal);     }     public Animal callFriend(String name){         return friends.get(name);     }}下面是一些包含大量类型转换的代码片段:Mouse jerry = new Mouse();jerry.addFriend("spike", new Dog());jerry.addFriend("quacker", new Duck()); ((Dog) jerry.callFriend("spike")).bark();((Duck) jerry.callFriend("quacker")).quack();我是否可以为返回类型使用泛型来消除类型转换,这样我就可以说jerry.callFriend("spike").bark();jerry.callFriend("quacker").quack();下面是一些带有返回类型的初始代码,作为一个从未使用过的参数传递给该方法。public<T extends Animal> T callFriend(String name, T unusedTypeObj){     return (T)friends.get(name);        }是否有一种方法可以在运行时不使用额外的参数来计算返回类型instanceof?或者至少传递一个类型的类,而不是一个虚拟实例。我知道泛型是用于编译时类型检查的,但是有解决办法吗?
查看完整描述

3 回答

?
富国沪深

TA贡献1790条经验 获得超9个赞

你可以定义callFriend这样:

public <T extends Animal> T callFriend(String name, Class<T> type) {
    return type.cast(friends.get(name));}

然后这样称呼它:

jerry.callFriend("spike", Dog.class).bark();jerry.callFriend("quacker", Duck.class).quack();

此代码的优点是不生成任何编译器警告。当然,这实际上只是一个更新版本的铸造前通用的日子,没有增加任何额外的安全。


查看完整回答
反对 回复 2019-07-04
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

没有。编译器不知道哪种类型jerry.callFriend("spike")会回来的。而且,您的实现只是在方法中隐藏强制转换,而没有任何额外的类型安全性。考虑到这一点:

jerry.addFriend("quaker", new Duck());jerry.callFriend("quaker", /* unused */ new Dog()); // dies with illegal cast

在这种情况下,创建一个抽象talk()方法并在子类中适当地重写它将更好地为您服务:

Mouse jerry = new Mouse();jerry.addFriend("spike", new Dog());jerry.addFriend("quacker", new Duck());
jerry.callFriend("spike").talk();jerry.callFriend("quacker").talk();


查看完整回答
反对 回复 2019-07-04
?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

您可以这样实现它:

@SuppressWarnings("unchecked")public <T extends Animal> T callFriend(String name) {
    return (T)friends.get(name);}

(是的,这是法律法规,见Java泛型:泛型类型定义为只返回类型.)

将从调用方推断返回类型。但是,请注意@SuppressWarnings注释:这告诉你这段代码不是类型错误..你必须亲自核实,否则你可以ClassCastExceptions在运行时。

不幸的是,您使用它的方式(不将返回值赋值给临时变量),使编译器高兴的唯一方法是这样调用它:

jerry.<Dog>callFriend("spike").bark();

虽然这可能比选角要好一些,但您最好还是把Animal分类摘要talk()方法,正如大卫·施密特所说。


查看完整回答
反对 回复 2019-07-04
  • 3 回答
  • 0 关注
  • 2399 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信