Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

A Strange case of Java Generic and Inheritage Parameter Passing

DZone's Guide to

A Strange case of Java Generic and Inheritage Parameter Passing

· Java Zone
Free Resource

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

I came a cross some strange Java code and I would like to share it here. Take a look few of classes I have here:

// file: AFoo.java
package atest.deng;
public abstract class AFoo<T> {
}

// file: Foo.java
package atest.deng;
public class Foo extends AFoo<String> {
}

// file: FooProcessor.java
package atest.deng;
public class FooProcessor<T> {
    public void process(Class<AFoo<?>> cls) {
        System.out.println(cls);
    }
}

// file: FooMain.java
package atest.deng;
public class FooMain {
    public static void main(String[] args) {
        new FooProcessor().process(Foo.class);
    }
}


bash> mvn compile
bash> [INFO] BUILD SUCCESS

I tried this with JDK6 + Maven and it compiles without problem. But try to remove the <T> part from FooProcessor and it will fail to compile!

// file: FooProcessor.java
package atest.deng;
public class FooProcessor {
    public void process(Class<AFoo<?>> cls) {
        System.out.println(cls);
    }
}

bash> mvn clean compile
bash> [ERROR] java-demo\src\main\javatest\deng\FooMain.java:[4,26] process(java.lang.Class<atest.deng.AFoo<?>>) in atest.deng.FooProcessor cannot be applied to (java.lang.Class<atest.deng.Foo>)

With the <T> the code won't compile, and yet we are not even using it in this case. How and why <T> affects the method parameters invocation?

Now, we can improve the FooProcessor in this way so that the presence of <T> doesn't have any affect.

package atest.deng;
public class FooProcessor {
    public void process(Class<? extends AFoo<?>> cls) {
        System.out.println(cls);
    }
}

That's a more proper way to write the generic parameter anyway. But despite a better solution, the puzzle is that the original code compiled under the compiler, but only with the <T> presented, and yet it's not used. Wouldn't you consider this as a Java compiler bug?

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Published at DZone with permission of Zemian Deng, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}