2

I have written generics code many times, without too much trouble. However, I just wrote some code that go wrong at runtime, and it is fine. But it should, in my understanding, also issue a compiler error, but it does not. Can anyone explain why?


import static org.junit.Assert.assertNotNull;

import org.junit.Test;

public class TestGenerics {
    interface I{}
    class A implements I{}

    private <Z extends I> Z get(){
        return (Z) new A();
    }

    @Test
    public void test() {
        A a1 = get();
        assertNotNull(a1);
        String b = get(); // this compiles. Why?
    }

}

Edit: don't focus on the cast to Z. I want to understand why the signature of the method say that It Is going to return something that implements I and i can assign It to a String without casting, as if String Is instanceof I which Is not

  • 1
    You have an unsafe cast inside `get()`. If you turn on compiler warnings, there should be a warning about it. When you make that cast, you assume responsibility for using types correctly. – khelwood Dec 06 '21 at 17:20
  • When you cast things like that, all bets are off. Casts are the programmers way to say to the compiler "I know more than you do". If you're wrong, then there's nothing the compiler can do. – Michael Dec 06 '21 at 17:22
  • That's a good question. Why doesn't the compiler know that `String` cannot possibly extend/implement `I`? – knittl Dec 06 '21 at 17:24
  • "Explicit casts" aka downcasts, from parent to child. These are the ones creating problems. – JayC667 Dec 06 '21 at 17:24

0 Answers0