0

I've stumbled upon a counterintuitive example of java compiler behavior (in this ru.so question). Given javac 1.8.0_161 and following code:

public class RuSo791351 {
    public static void main(String[] args) {
        List<Integer> payload = Arrays.asList(1, 2, 3);
        Consumer uncheckedConsumer = new Consumer();
        uncheckedConsumer.consume(payload);
        Consumer<?> wildcardConsumer = new Consumer<>();
        wildcardConsumer.consume(payload);
        Consumer<Integer> typedConsumer = new Consumer<>();
        typedConsumer.consume(payload);
    }

    private static class Consumer<T> {
        public <V> void consume(Collection<V> collection) {
            System.out.println("consume(Collection<T>) called");
        }

        public void consume(List<String> strings) {
            System.out.println("consume(List<String>) called");
        }
    }
}

compiler would be expected to either take type erasure into account and take the easy way, emitting bytecode for consume(List<String>) call every time, or take the hard way and emit bytecode for consume(Collection<V>) - again, every time. However, compiler emits consume(List<String>) for uncheckedConsumer and consume(Collection<V>) for other cases:

40: invokevirtual #7                  // Method me/etki/wtf/so/RuSo791351$Consumer.consume:(Ljava/util/List;)V
...
54: invokevirtual #8                  // Method me/etki/wtf/so/RuSo791351$Consumer.consume:(Ljava/util/Collection;)V
...
70: invokevirtual #8                  // Method me/etki/wtf/so/RuSo791351$Consumer.consume:(Ljava/util/Collection;)V

So it seems that if i don't specify <T> parameter for Consumer class at all, compiler ignores all generic information contained in class - even though <V> is a completely different method parameter - and compiler chooses List over Collection as a more precise type. I'm nearly sure this is an effect of backwards compatibility for pre-generic era code, but couldn't find anything specific in JLS (to be honest, it seems i don't even know how to ask google about this). Can anyone point me to the specification of such behavior?

Etki
  • 2,042
  • 2
  • 17
  • 40

0 Answers0