Youssef Khloufi
Youssef Khloufi

Reputation: 705

Groovy List<List<Integer>> behaving like List<Integer>

I discovered in a production code a casting from List<List<Integer>> to List<Integer> which does not make any sense, but it's working without any problem being raised, so I wrote a quick test to check it out and to my surprise a List<List<Object>> can behave like a List<Object>

    static void main(String[] args) {
        List<List<Integer>> list = []
        list.add(1)
        println(list.get(0))
        println(list.get(0).getClass())
    }

the output is:

    1
    class java.lang.Integer

I understand that we can define lists containing values of heterogeneous types like def heterogeneous = [1, "a", true], but in the example above the static typing clearly indicates that it should be List<List<Integer>>

Any explanation of the weird behavior ?

Upvotes: 2

Views: 482

Answers (1)

injecteer
injecteer

Reputation: 20699

In straight-forward Groovy code, the type checking of Lists or other generic typed objects is weak.

Meaning that a List<List<Integer>> can be fed with any objects, like Strings, integers or arrays.

To make the type checking real, you should use @CompileStatic or @TypeChecked annotations like so:

@groovy.transform.CompileStatic
def getInts(){
  List<List<Integer>> ints = []
  ints << 1
  ints << [ '2' ]
  ints << [ 3 ]
}

getInts()

The code above throws 2 compilation errors:

startup failed:
Script1.groovy: 4: [Static type checking] - Cannot call <T> java.util.List <List>#leftShift(T) with arguments [int] 
 @ line 4, column 3.
     ints << 1
     ^

Script1.groovy: 5: [Static type checking] - Cannot call <T> java.util.List <List>#leftShift(T) with arguments [java.util.List <java.lang.String>] 
 @ line 5, column 3.
     ints << [ '2' ]
     ^

2 errors

so that only the line ints << [ 3 ] is valid.

Upvotes: 4

Related Questions