Pergunta

So I was writing a Minecraft Forge mod, in eclipse, and I came around an eclipse warning that was very confusing. Though I have developed for a lot know, I do not know what the following text means.

The argument of type Block[][] should explicitly be cast to Object[][] for the invocation of the varargs method fooMethod(Object[]...) from type FooClass. It could alternatively be cast to Object[] for a varargs invocation

My Java Code:

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);

If someone could very kindly dumb it down a little Itsy bit.

Foi útil?

Solução

It's because what you're doing is ambiguous. It is unclear whether you're trying to do this:

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

or this:

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

Doing it the first way, when you iterate over the argument in the method each element will be an element from the 2d array. So each element will be a 1 dimensional array and there will be the same number of elements as their were in the 2d array.

Doing it the 2nd way, regardless of how many arrays were in the original array, when you iterate over the parameter in the method you will get one element and it will be the original 2d array.

Outras dicas

To understand this, you (unfortunately) need to know how Java internally implements them.

The method signature, internally, becomes:

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

(See JLS 15.12.4.2)

You can invoke a varargs method in two ways, either by passing all arguments as an array, or by passing them one-by-one as separate parameters. If you only provide one argument, the compiler needs to decide whether you are intending to pass only one argument as a variable argument list, or whether you are passing all your arguments as an array (with potentially many arguments).

The problem is exacerbated by the fact that an Object[] itself can is also an Object, so an Object[][] can be assigned to Object[] can be assigned to Object.

If you cast your array as Object[][] as the compiler suggests, it thinks that you are passing all varargs in one array (potentially many). If you cast it to Object[], it thinks you are passing a single vararg argument.

In this confusing case, I would advise not to use varargs - they are syntactic sugar anyway and in this case they provide more confusion than that they add convenience.

To to that, just declare your method as:

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

From what you write in a comment on the answer above, this should fix your problem (since you are passing in a Block[][] argument to the method invocation)

... but ...

You may have a bigger problem - this will cause an exception at runtime because registerBlock is not expecting a two-dimensional array of Blocks (which you say you are passing in) Instead, it expects the inner array to contain two Integers and then one Block.

That's not a good object-oriented style and it is the root cause of your problems.

You need to wrap these two integers and the Block into a class:

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; }
}

and then your method becomes:

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
    }
}

Check this line

for (Object[] b : blocks){

blocks should be 2 dimensional object array.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top