General methods and methods of type input in Java

Given the following not very useful code:

package com.something; import java.util.ArrayList; import java.util.Collection; //Not a generic class! public class Test { public <T> void plain(T param1, T param2) {} public <T> void fancy(T param1, Collection<T> param2) {} public void testMethod() { //No error fancy("", new ArrayList<String>()); //Compiler error here! fancy("", new ArrayList<Integer>()); //No error plain("", new ArrayList<Integer>()); } } 

(Please correct my understanding if it is not so!)

The second call to fancy() is a compiler error, because Java cannot infer any common type between the two arguments (cannot infer Object , since the second parameter must be Collection .)

The plain() call is not a compiler error, because Java passes a generic Object type between two arguments.

I recently met code that had a method signature similar to plain() .

My question is:

Is plain() signature useful for anything?

Perhaps the person who wrote this code thought that the plain() signature would ensure that both parameters had the same type at compile time, which is obviously not the case.

Is there any difference or usefulness for writing a method with a signature of type plain() , and not just for defining both parameters as Object s?

+8
java generics type-inference
source share
3 answers

While the compiler does not output a generic type that it can use, it will apply type restrictions that are explicitly specified. The next call causes a type error.

 this.<String>plain("", new ArrayList<Integer>()); /* Compiler error. */ 

The parameterized <String> plain (String, String) method of type Test is not applicable for arguments (String, ArrayList <Integer>)

+4
source share

I think you could say that this is some kind of documentation, so the user knows that you expect both arguments to be of the same type. Of course, any two objects are of the same type to some extent (they are all Object ), so this is a meaningless statement.

In short, this is a useless signature.

Of course, if plain returns a type T , it will be a different story.

+3
source share

The second call to fancy () is a compiler error, because Java cannot infer any common type between two arguments (cannot invoke Object with the second parameter, there must be a collection.)

Well, I'm not sure if this is the reason, I would say, the reason is that the general type T in Collection<T> is an invariant whose value determines the type of the first parameter T

For example, this is valid:

 fancy("", new ArrayList<CharSequence>()); //compiles Ok 

Because all are String CharSequences . The first parameter is CharSequence be CharSequence as soon as the type is inferred from ArraysList<CharSequence> .

However, this is not true:

 fancy((CharSequence)"", new ArrayList<String>()); //compiler error 

Since the type of the first parameter is expected to be String , and we cannot guarantee that all CharSequences are essentially a String type, right?

So, AFAIK, the reason the types are incompatible is due to the nature of the generics in this case, and not the fact that the second type is Collection .

+1
source share

All Articles