5

given a generic interface:

public interface I<E> {
    public int interfaceMethod(E s);
}

and a generic class that implements the interface

public class A<T> implements I<T> {

    private T val;

    public A(T x) {
        val = x;
    }

    public int interfaceMethod(T val) {
        // looks like T should be of the same type as instance variable 'val'
        return 0;
    }

}

why does the following work?

public class Run {

    public static void main(String[] args) {

        A a = new A<String>("hello");

        System.out.println(a.interfaceMethod(100)); \\ returns 0
    }
}

I expected the T type parameter of the method interfaceMethod as defined in class A to constrain the method to arguments that have the same type as that supplied to the constructor of A. (in this case String).

Why does a.interfaceMethod not require an argument of type String?

beoliver
  • 5,579
  • 5
  • 36
  • 72
  • probably because I didn't do the following `A a = new A("hello");`... – beoliver Jul 06 '15 at 10:42
  • I would venture that the integer is implicitly cast to String http://stackoverflow.com/questions/9159358/implicit-cast-to-string-tostring-and-int – JoSSte Jul 06 '15 at 10:43
  • http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it – JB Nizet Jul 06 '15 at 10:44

3 Answers3

1

That happens because you ignored the warning "Raw use of parameter a" (or something like that)

Use:

A<String> a = new A<String>("hello");

When ignoring generic related warnings the code may compile when shouldn't.

BobTheBuilder
  • 18,858
  • 6
  • 40
  • 61
1

This works because a instance is typed to A class only
You should type it like this:

A<String> a = new A<String>("hello");

If you wont specify the parameter, you will be able to put there all data types like String, int etc.

maskacovnik
  • 3,080
  • 5
  • 20
  • 26
1

While the other answers explained that a compiler warning should normally show up. The explanation I was looking for came in the form of the link to a previous post provided by @JB Nizet.

T t = new T<S>()

is not the same as

T<S> t = new T<S>()

The first is an example of a raw type. I was interested in why this works (i.e... if it compiles and does not throw a run-time error) then there must be something to it.

The answers of that post are detailed and explain exactly why this compiles (long story short, backwards compatibility). The post goes into full detail and explains the implications for Java's type system.

Community
  • 1
  • 1
beoliver
  • 5,579
  • 5
  • 36
  • 72