“类型X [] []应该显式地转换为Object [] []来调用varargs”

时间:2014-01-25 02:47:52

标签: java eclipse warnings variadic-functions

所以我在日食中写了一个Minecraft Forge mod,我发现了一个令人困惑的日食警告。虽然我已经开发了很多知识,但我不知道下面的内容是什么意思。

  

类型Block [] []的参数应该显式地转换为Object [] [],以便从类型FooClass调用varargs方法fooMethod(Object [] ...)。也可以将其转换为Object []以进行varargs调用

我的Java代码:

fooMethod:

    public static void registerBlock(Object[]...blocks){
    for (Object[] b : blocks){
        Block block = (Block) b[2];
        Integer[] bb = {(int) b[0], (int) b[1]};

        blocksID.put(bb, (Block) block); //Block ID
        unlocalName.put(block.getUnlocalizedName(), bb);//Unlocal Name
        localName.put(block.getLocalizedName(), bb); //Local Name
    }

fooMethodWithWarning:

this.registerBlock(blocks);

如果有人能够非常友善地将它愚蠢地点了一下。

3 个答案:

答案 0 :(得分:1)

这是因为你所做的是含糊不清的。目前还不清楚你是否想要这样做:

// Calls the vararg method with multiple arguments
// (the arrays in blocks).
registerBlock((Object[][]) blocks);

或者这个:

// Calls the vararg method with a single argument (the blocks object)
registerBlock((Object[]) blocks);

第一种方式,当你遍历方法中的参数时,每个元素都将是2d数组中的一个元素。因此,每个元素都是一维数组,并且元素数量与二维数组中的元素数量相同。

第二种方式,无论原始数组中有多少个数组,当你在方法中迭代参数时,你将获得一个元素,它将是原始的2d数组。

答案 1 :(得分:1)

要理解这一点,你(不幸的是)需要知道Java如何在内部实现它们。

方法签名在内部变为:

public static void registerBlock(Object[][] blocks)

(见JLS 15.12.4.2)

您可以通过两种方式调用varargs方法,方法是将所有参数作为数组传递,或者将它们作为单独的参数逐个传递。如果只提供一个参数,编译器需要决定是否打算只将一个参数作为变量参数列表传递,或者是否将所有参数作为数组传递(可能有很多参数)。

由于Object []本身也可以是一个Object,因此可以将Object [] []赋给Object []的事件可以分配给Object。

如果您将数组转换为Object [] [],正如编译器所建议的那样,它认为您将所有varargs传递到一个数组中(可能很多)。如果将其强制转换为Object [],则认为您传递的是单个vararg参数。

在这个令人困惑的情况下,我建议使用varargs - 无论如何它们都是语法糖,在这种情况下,它们提供的混乱比它们增加便利性更多。

为此,只需将您的方法声明为:

public static void registerBlock(Block[][] blocks)

从你在上面的答案的评论中写的,这应该解决你的问题(因为你传递方法调用的Block [] []参数)

......但......

你可能有一个更大的问题 - 这会在运行时导致异常,因为registerBlock不期望一个二维的Blocks数组(你说你传入了) 相反,它期望内部数组包含两个整数,然后包含一个Block。

这不是一个好的面向对象的风格,它是你问题的根本原因。

您需要将这两个整数和Block包装成一个类:

public class BlockRegistration {
    private int x;
    private int y ;
    private Block block;

    // [...]

    public Block getBlock() { return block; }
    public int getX() { return x; }
    public int getY() { return y; }
}

然后您的方法变为:

public static void registerBlock(BlockRegistration... blocks) {
    for (BlockRegistration b : blocks) {
        Block block = b.getBlock();
        Integer[] bb = { b.x, b.y };

        blocksID.put(bb, block); // Block ID
        unlocalName.put(block.getUnlocalizedName(), bb);// Unlocal Name
        localName.put(block.getLocalizedName(), bb); // Local Name
    }
}

答案 2 :(得分:0)

检查此行

for (Object[] b : blocks){

块应该是2维对象数组。