Type Argument Inference by Return Value

This section provides a tutorial example on type argument inference by return value. The compiler will deduce the type argument by looking at the context where the return value is used. if the type parameter is not used in the method argument list.

As described earlier, if type argument is not specified explicitly when invoking a generic method, the compiler will perform the type argument inference process. It will look at method argument list first to deduce the type argument, if the type parameter is used in there. If not, the compiler will look at the return value do the job.

Here is another tutorial example to show you how the compiler uses the return value to deduce the argument type:

/* TypeInferenceByReturnValue.java
 - Copyright (c) 2014, HerongYang.com, All Rights Reserved.
 */
class TypeInferenceByReturnValue {
   public static <T> T alias(Object o) {
      return (T) o;
   }
   public static void main(String[] a) {
      String s = "1234";

      /* Test 1 - Type argument specified as String */
      String as 
         = TypeInferenceByReturnValue.<String>alias(s);
      System.out.println("Alias: "+as);

      /* Test 2 - Type argument inferred to String
                  by looking at the assignment operation
      String bs = TypeInferenceByReturnValue.alias(s);
      System.out.println("Alias: "+bs);
      */

      /* Test 3 - Type argument inferred to String
                  by looking at the invocation context
      Object ao = "Hello "+TypeInferenceByReturnValue.alias(s);
      System.out.println("Alias: "+ao);

      /* Test 4 - Type argument inferred to Long
                  but runtime exception occurred
      Long al = TypeInferenceByReturnValue.alias(s);
      System.out.println("Alias: "+al);
      */

      /* Test 5 - Type argument inferred to Short
                  but runtime exception occurred
      Number an = (Short) TypeInferenceByReturnValue.alias(s);
      System.out.println("Alias: "+an);
      */

      /* Test 6 - Type argument inferred to Object:
                  but failed to compile the entire statement
      Integer ai 
         = Integer.valueOf(TypeInferenceByReturnValue.alias(s));
      System.out.println("Alias: "+ai);
      */
   }
}

On test 1, I was not using type argument inference. So there was no compilation issue except an "unchecked" warning at the (return (T) o;) statement. See the result below:

C:\herong>javac TypeInferenceByReturnvalue.java

Note: TypeInferenceByReturnvalue.java uses unchecked or unsafe 
   operations.
Note: Recompile with -Xlint:unchecked for details.

C:\herong>java TypeInferenceByReturnValue

Alias: 1234

On test 2, I let the compiler to do the type inference. The compiler did a good job to deduce the type argument to be "String" by looking at the left side of the assignment operation. See the result below:

Alias: 1234
Alias: 1234

On test 3, the compiler also did a good job to deduce the type argument to be "String" by looking at the expected type of the string concatenation operation. See the result below:

Alias: 1234
Alias: Hello 1234

On test 4, the compiler did an ok job and deduced the type argument to be "Long" by looking at the left side of the assignment operation. But this caused a runtime ClassCastException:

Alias: 1234
Exception in thread "main" java.lang.ClassCastException: 
   java.lang.String cannot be cast to java.lang.Long
at TypeInferenceByReturnValue.main(TypeInferenceByReturnvalue.java:30)

On test 5, the compiler did an ok job and deduced the type argument to be "Short" by looking at the cast operation on the return value. But this caused a runtime ClassCastException:

Exception in thread "main" java.lang.ClassCastException: 
java.lang.String cannot be cast to java.lang.Short
at TypeInferenceByReturnValue.main(TypeInferenceByReturnvalue.java:36)

On test 6, the compiler in JDK 1.7 failed to deduce the type argument to a type that can meet the requirement of Integer.valueOf(). It used the default type, "Object", as the type argument, leading to a compilation error on Integer.valueOf():

TypeInferenceByReturnvalue.java:44: error: no suitable method found 
for valueOf(Object)
         = Integer.valueOf(TypeInferenceByReturnValue.alias(s));
                  ^
    method Integer.valueOf(int) is not applicable
      (actual argument Object cannot be converted to int by method 
      invocation conversion)
    method Integer.valueOf(String) is not applicable
      (actual argument Object cannot be converted to String by method
      invocation conversion)
    method Integer.valueOf(String,int) is not applicable
      (actual and formal argument lists differ in length)

However, the compiler in JDK 1.8 is not generating any errors on test 6. It returns expected result of "Alias: 1234".

If you want to see more examples of using generic methods and type argument inference, see the next section.

Last update: 2014.

Table of Contents

 About This Book

 Installing JDK 1.8 on Windows

 Execution Process, Entry Point, Input and Output

 Primitive Data Types and Literals

 Bits, Bytes, Bitwise and Shift Operations

 Managing Bit Strings in Byte Arrays

 Reference Data Types and Variables

 StringBuffer - The String Buffer Class

 System Properties and Runtime Object Methods

 Generic Classes and Parameterized Types

Generic Methods and Type Inference

 What Is a Generic Method?

 Comparing Generic Method with Non-Generic Method

 Non-Generic Method Example - maxNonGeneric()

 Generic Method Example - maxGeneric()

 Generic Methods in java.util.Collections Class

 Testing Generic Methods in Collections Class

 What Is Type Argument Inference?

 Type Argument Inference by Parameter List

Type Argument Inference by Return Value

 Generic Methods using Parameterized Types

 Parameterized Type as Generic Method Return Type

 Lambda Expressions and Method References

 Execution Threads and Multi-Threading Java Programs

 ThreadGroup Class and "system" ThreadGroup Tree

 Synchronization Technique and Synchronized Code Blocks

 Deadlock Condition Example Programs

 Garbage Collection and the gc() Method

 Outdated Tutorials

 References

 PDF Printing Version