bkmoney
bkmoney

Reputation: 1256

Non-generic subclass of generic interface

I have some generic interface

interface Animal<T> {}

And I have a subclass that I only want to extend Animal<Object>. So I did

class Pet implements Animal<Object>

I have some method that should only compile if both parameters have matching type:

<T> T apply(T source, Animal<T> target)

I was wondering, why does this compile

String source = "test";
Pet pet = new Pet();
apply(source, pet);

It seems that since the type of source is String, and the type of pet is Pet which implements Animal<Object>, there should be a type mismatch here and cause a compiler error, but I found that this compiles and was wondering if someone could explain why.

Upvotes: 1

Views: 255

Answers (3)

user11595728
user11595728

Reputation:

Because you are calling method apply without explicitly specifying a type between angle brackets, you are relying on the compiler to infer one for you. If you try assigning the result to a variable of some type, say String, the compiler will tell you which type it has inferred for example:

String r = Animal.apply(source, pet);

Type mismatch: Cannot convert from Object to String

In which case you know that T was inferred as Object. If you pass two String instances, T will be inferred as String:

String r = Animal.apply("A", "B");

Note that Java allows you to explicitly specify the type argument for a generic method (called type witness). This is useful to check assumptions you might have about how the type parameter will be bound:

Animal.<Object>apply(source, pet);

More information: Java Tutorial

Upvotes: 1

KNPS
KNPS

Reputation: 16

You are casting binding the generic in

class Pet implements Animal<Object>

to the object class. Everything in java is a descendant of the object class so the compiler will have no issue here. When you declare that your class implements Animal you need to bind it to a specific type to restrict what it will accept for parameters.

Upvotes: 0

rzwitserloot
rzwitserloot

Reputation: 102923

String is also an Object (all non-primitives are also Objects). so, the apply method here works fine, and binds T to object, at which point everything lines up. It's like having a method: foo(Object x), and calling it as foo("") which is perfectly fine.

Upvotes: 0

Related Questions