Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Methods and Type Inferencing 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's wrong!)

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

The call to plain() is not a compiler error because Java infers the common type of Object between the two arguments.

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

My question is this:

Is plain()'s signature useful for anything?

Perhaps the person who wrote that code thought that plain()'s signature would enforce that both parameters have the same type at compile time, which is obviously not the case.

Is there any difference from or benefit to writing a method with a signature like plain() rather than just defining both parameters to be Objects?

like image 788
segfault Avatar asked Jul 16 '12 22:07

segfault


2 Answers

While the compiler does not infer the generic type one might intend, it will enforce type constraints that are explicitly specified. The following invocation results in a type error.

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

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

like image 89
erickson Avatar answered Nov 04 '22 01:11

erickson


I guess you could say it serves as some sort of documentation, so that 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 degree (they're all Object), so it's a meaningless statement.

Long story short, it's a useless signature.

Of course, if plain returned a type T, that'd be a different story.

like image 41
yshavit Avatar answered Nov 04 '22 02:11

yshavit