Java Tutorials - Herong's Tutorial Examples - Version 7.03, by Dr. Herong Yang
Parameterized Type as Generic Method Return Type
This section provides a tutorial example of using a generic method, emptyList(), from the java.util.Collections class. The type parameter is used only in the return type definition, no in the method parameters definition.
In the previous tutorial, we tested the "<T> List<T> singletonList(T o)" generic method and learned how the compiler uses the input argument expression to perform type argument inference to determine the type parameter, T.
In this tutorial, we will see how the compiler determines the actual type of the type parameter, T, if it is only used in the return type. Here is a tutorial example program that uses the "<T> List<T> emptyList()" generic method.
/* GenericMethodsEmptyList.java - Copyright (c) 2014, HerongYang.com, All Rights Reserved. */ import java.util.*; class GenericMethodsEmptyList { public static void main(String[] a) { testEmptyList(); } public static void testEmptyList() { java.io.PrintStream o = System.out; o.println("Testing: <T> List<T> emptyList()"); List<String> ls = Collections.emptyList(); o.println(" Class name of ls: "+ls.getClass().getName()); List<?> lw = (List<?>) Collections.emptyList(); o.println(" Class name of lw: "+lw.getClass().getName()); // Compiler error: inconvertible types // List<Number> ln = (List<Number>) Collections.emptyList(); } }
Compile and run the example, you will get:
Testing: <T> List<T> emptyList() Class name of ls: java.util.Collections$EmptyList Class name of lw: java.util.Collections$EmptyList
Looking at the first statements where the generic method are invoked (List<String> ls = Collections.emptyList();) and (List<?> lw = (List<?>) Collections.emptyList();), here is my guesses on how the compiler determines the actual type of the type parameter, T, and did the type checking on the statement:
The behavior of using the default type of Object as the type parameter by the compiler can be demonstrated better, if you uncomment the (List<Number> ln = (List<Number>) Collections.emptyList();) statement and try to compile it again in JDK 1.8, you see this error:
GenericMethodsEmptyList.java:20: error: incompatible types: List<Object> cannot be converted to List<Number> List<Number> ln = (List<Number>) Collections.emptyList(); ^ 1 error
If you compile it with JDK 1.7, the error message is different:
GenericMethodsEmptyList.java:20: error: inconvertible types List<Number> ln = (List<Number>) Collections.emptyList(); ^ required: List<Number> found: List<Object> 1 error
The "found: List<Object>" part of the error confirms that the compiler assumes that (Collections.emptyList();) has a default type of "List<Object>".
Last update: 2014.
Table of Contents
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
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