gpt4 book ai didi

java - 对泛型类和 ArrayLists 的困惑

转载 作者:搜寻专家 更新时间:2023-11-01 02:10:03 24 4
gpt4 key购买 nike

这是我为问题的上下文制作的一组类

水族类:

package test;

import java.util.ArrayList;

public class Aquarium {

// the aquarium is composed of fish tanks

ArrayList<Object> aquarium;

public Aquarium(){

aquarium = new ArrayList<Object>();

}

public <T> void addFishToTank(int index, T fish){

FishTank<T> tank = (FishTank<T>) aquarium.get(index);
tank.addFish(fish);

}


public ArrayList<Object> getAquarium(){

return aquarium;

}

public String toString(){

String holder = "";

int i = 0;

for (Object tank : aquarium){

holder += "Tank " + i + ":\n";

holder += tank.toString();

i ++;

}

return holder;

}

public static void main(String[] args){


Aquarium seaWorld = new Aquarium();

seaWorld.getAquarium().add(new FishTank<Salmon>());

seaWorld.addFishToTank(0, new Salmon());
seaWorld.addFishToTank(0, new Grouper());

System.out.println(seaWorld.toString());

}

}

鱼缸类:

package test;

import java.util.ArrayList;

public class FishTank<T>{

// inside each fish tank there is a group of fish

ArrayList<T> fishGroup = new ArrayList<T>();

public void addFish(T element){

fishGroup.add(element);

}

public String toString(){

String holder = "";

for (T fish: fishGroup){

holder += fish.toString() + "\n";

}

return holder;
}


}

鲑鱼类:

package test;

public class Salmon {

public String toString(){

return "This is a salmon";
}

}

石斑鱼类:

package test;

public class Grouper {

public String toString(){

return "This is a grouper";
}

}

所有代码都可以正常编译,Aquarium 的输出结果为

Tank 0:
This is a salmon
This is a grouper

这怎么可能?当我把鱼缸添加到水族箱中时

seaWorld.getAquarium().add(new FishTank<Salmon>());

指定它是一个只能容纳 Salmon 对象的 FishTank。首先,我添加了一个 Salmon 对象

seaWorld.addFishToTank(0, new Salmon());

这很好,因为水族馆索引 0 处的鱼缸是一个装有鲑鱼对象的鱼缸。但是,当我将一个 Grouper 对象添加到索引 0 处的鲑鱼缸时

seaWorld.addFishToTank(0, new Grouper());

它仍然将石斑鱼添加到水箱中。运行时不应该抛出异常吗?那么,我怎样才能强制只将 Salmon 对象添加到 Salmon 容器中?

最佳答案

泛型仅用于编译时类型安全。如果您想要一个具有单独类型的水箱的水族馆,其底层鱼类类型在编译时是未知的,那么您在 Java 中就不走运了。更糟糕的是,因为泛型类型在编译期间都被删除了,所以你剩下的是 Object。无处不在。

没有类转换异常的原因是因为在运行时它只是一个 FishTank (原始类型)在每个数组索引处,您可以在其中自由混合鱼(或陆生动物,或心理构造)。

解决此类问题的一种方法是通过包含 Class< T > 使您的 FishTank 在运行时了解其成员资格。 field 。然后坦克可以在 addFish() 期间进行运行时检查。 ,虽然上述检查的严格性是有限的(例如,如果您的鱼本身是一个通用容器,您仍然可以在同一个水箱中混合容器;getClass() 返回一个“已删除”的类对象)。

关于java - 对泛型类和 ArrayLists 的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20432841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com