我正在阅读一本有关带有Java示例的OOP模式的书。 书中的类代码示例:
public class Board {
private int width, height;
private List tiles;
...
private void initialize() {
tiles = new ArrayList(width);
for (int i=0; i<width; i++) {
tiles.add(i, new ArrayList(height));
for (int j=0; j<height; j++) {
((ArrayList)tiles.get(i)).add(j, new Tile());
}
}
}
public Tile getTile(int x, int y) {
return (Tile)((ArrayList)tiles.get(x-1)).get(y-1);
}
}
为什么在上述两种方法中都使用了显式类型转换?第一种情况是在第((ArrayList)tiles.get(i)).add(j, new Tile());
行中使用 ArrayList ,第二种情况是在return (Tile)((ArrayList)tiles.get(x-1)).get(y-1);
行中使用 Tile 。我的意思是,这是脚本作者的观点还是在Java情况下必需的?
答案 0 :(得分:3)
这是较早的Java代码,在引入泛型之前,因此List
接口返回Object
而不是所需的类型。用现代的话来说,他们似乎想要
private List<List<Tile>> tiles;
然后initialize
(假设我没有打错字)可能像这样:
private void initialize() {
tiles = new ArrayList<>(width);
for (int i=0; i<width; i++) {
tiles.add(i, new ArrayList<>(height));
for (int j=0; j<height; j++) {
tiles.get(i)).add(j, new Tile();
}
}
}
(我相信原始代码中的Array
是ArrayList
的错字)
和
public Tile getTile(int x, int y) {
return tiles.get(x-1).get(y-1);
}
答案 1 :(得分:1)
好像您正在读一本古籍。
为什么在上述两种方法中都使用了显式类型转换?
这是必需的,因为您正在处理raw types
我的意思是,这是脚本作者的观点还是在Java情况下必需的?
如果您使用generics,则无需投射。
答案 2 :(得分:1)
有两种方法来声明ArrayList。
为使示例更简单,我创建了以下虚拟类
public class Tile {
int x = 123;
}
您在问题中描述的第一种较旧的方式可能写为
List tiles = new ArrayList();
tiles.add(new Tile());
Tile tile = ((Tile)tiles.get(0));
System.out.println(tile.x); // prints 123
使用泛型可以完成相同的事情。
List<Tile> tiles = new ArrayList<>();
tiles.add(new Tile());
Tile tile = tiles.get(0);
System.out.println(tile.x); // prints 123
使用泛型时,不需要使用强制转换,这是使用列表的首选方式。
答案 3 :(得分:1)
我尝试测试您的代码。我不确定您指定的代码是否完全正确。
我认为
tiles = new Array(width);
应该是
tiles = new ArrayList(width);
更多
((ArrayList)tiles.get(i)).add(j, new Tile());
在此处tiles.get(i)被类型转换为ArrayList,因为tiles是一个List,每个元素都拥有自己的ArrayList。 (这是2D动态数组创建代码)
当前tiles.get(i)
返回一个Object类型。必须将其类型转换为ArrayList才能使用方法“ add”
在下面类似,对象被类型转换为ArrayList 以使用方法“ get”
答案 4 :(得分:0)
Java是强类型语言。大多数\所有类型错误必须在编译时获得。在泛型之前,您无法控制List中存储的类型。在这种情况下(原始类型),推迟的类型检查将进入运行时。然后最好先将任何原始类型转换为具体类型,以避免运行时错误。
但是在此示例中,我们甚至无法编译代码,因为一个示例说明了Raw类型可能是多么不可靠,并且编译器在编译时就理解了这一点。我的意思是这个字符串:mtcars
-是一个不言自明的简单案例。如果我们删除(ArrayList)并得到ggplot(mtcars_plot, aes(x = wt, y = mpg)) +
geom_point() +
geom_smooth(aes(), method=lm, se=F, fullrange=TRUE) +
geom_ribbon(aes(ymin = Low, ymax = High, fill = group), alpha = .25) +
labs(fill = "Weight Class") +
scale_fill_manual(values = c("red", "orange"), name = "fill")
-为什么Java编译器必须相信我们,在((ArrayList)tiles.get(i)).add(j, new Tile());
中,我们有一个List或一些带有(tiles.get(i)).add(j, new Tile());
方法?是的,不是必须的,他不是。
要进行检查,我们可以尝试使用原始类型编译简单的类似示例,以防List变量:
(tiles.get(i))
但是,当我们说到add()
中有关确切类型的编译器时,一切都会好的:
List listOfLists = new ArrayList();
listOfLists.add(0, new ArrayList());
(listOfLists.get(0)).add("something"); // compile error
泛型可以更准确地解决此问题。他们严格固定List变量的类型:
listOfLists.get(0)
编译器知道((ArrayList)listOfLists.get(0)).add("something"); // NO compile error
是一个列表,并且具有List<List> listOfLists = new ArrayList<List>(); // now List only have List's inside
listOfLists.add(0, new ArrayList());
(listOfLists.get(0)).add("something"); // NO compile error
方法。