5

I'm curious to understand why testInnerClass fails to compile, citing:

incompatible types: Object cannot be converted to String.

import java.util.List;

class Test<
        I extends Test.InnerClass,
        S extends Test.StaticInnerClass,
        O extends OtherClass> {

    void testOtherClass(O other) {
        String firstString = other.strings.get(0); //this works
    }
    
    void testStaticInnerClass(S staticInner) {
        String firstString = staticInner.strings.get(0); //this works
    }
    
    void testInnerClass(I inner) {
        String firstString = inner.strings.get(0); //this fails:
        //"incompatible types: Object cannot be converted to String" 
    }

    static class StaticInnerClass {
        List<String> strings;
    }
    
    class InnerClass {
        List<String> strings;
    }
}

class OtherClass {
    List<String> strings;
}

testStaticInnerClass and testOtherClass work as I would expect but I'm not exactly sure why testInnerClass fails.

Gautham M
  • 4,816
  • 3
  • 15
  • 37
Jota
  • 63
  • 5

1 Answers1

4

InnerClass is an inner class of Test which expects generic parameters. So you need to update the class declaration as:

class Test<
        I extends Test<I,S,O>.InnerClass,
        S extends Test.StaticInnerClass,
        O extends OtherClass>

The StaticInnerClass, even though inside Test, it is declared static.So as every static method or variable, the static class also does not depend on any state of the class. Hence it is not required to have S extends Test<I,S,O>.StaticInnerClass

Gautham M
  • 4,816
  • 3
  • 15
  • 37
  • 2
    Based on OP recent update new solution would be `Test.InnerClass, ...>`. Anyway more info about the issue: [What is a raw type and why shouldn't we use it?](https://stackoverflow.com/q/2770321) – Pshemo Mar 14 '21 at 16:20
  • Aha! Thanks Gautham for the clear, concise answer. – Jota Mar 14 '21 at 18:45