Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics and Static Factory Methods -- Syntax

Here's what I've got:

public class Node<T> {      // instance variables     private Node<T> next;     private T data;      // construct with data     private Node(T data){         next = null;         this.data = data;     }      // construct without data     private Node(){         next = null;         this.data = null;     }      // static factory method     public static <T> Node<T> newNodeWithData(T data){         return new Node<T>(data);     }      // static factory method     public static <T> Node<T> newNode(){         return new Node<T>();     } ... } 

My question really just about the syntax of generics coupled with that of a static factory method. I don't really understand why we put the < T > before the return type in the method declaration. Is it kind of like typecasting? Any help would be much appreciated!

like image 853
FateNuller Avatar asked Dec 23 '13 22:12

FateNuller


People also ask

How do you use generics with static methods?

For static generic methods, the type parameter section must appear before the method's return type. The complete syntax for invoking this method would be: Pair<Integer, String> p1 = new Pair<>(1, "apple"); Pair<Integer, String> p2 = new Pair<>(2, "pear"); boolean same = Util. <Integer, String>compare(p1, p2);

Which of the following is correct generic method syntax in Java?

4. Which of these is an correct way of defining generic method? Explanation: The syntax for a generic method includes a type parameter, inside angle brackets, and appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type.

Can factory methods be static?

A static factory method is a public static method on the object that returns a new instance of the object. These type of methods share the same benefits as the traditional factory method design pattern. This is especially useful for value objects that don't have a separate interface and implementation class.

How do you write a factory method in Java?

It is a creational design pattern which talks about the creation of an object. The factory design pattern says that define an interface ( A java interface or an abstract class) and let the subclasses decide which object to instantiate.


2 Answers

What you're asking about is type inferrence.

Since it's a static method it has to infer the Generic type from somewhere; You don't have an instance of the class. That's what the <T> means.

In the case of your method that takes no arguments it's actually inferring it from the target of the assignment. For example, say your method looked like this:

public static <T> List<T> getNewList() {     return new ArrayList<T>(); } 

When using this method, T is inferred from the target (in this case String):

List<String> myList = MyClass.getNewList(); 

In your other static method where you have a Generic argument, T is being inferred from the type being passed in:

public static <T> List<T> getNewListWithElement(T element) {     List<T> list = new ArrayList<T>();     list.add(element);     return list; } 

Here, if you tried doing:

List<String> myList = MyClass.getNewListWithElement(new Integer(4)); 

It would tell you that your target type was wrong, and you needed a List<Integer>

Specifically this is covered in sections 15.12.2.7 and 15.12.2.8 of the JLS.

like image 101
Brian Roach Avatar answered Sep 20 '22 06:09

Brian Roach


The reason you must decorate the static method with such sugar is because, as a static method, it does not inherit the T from the declaration of the class.

You could just as well do:

// static factory methods public static <Q> Node<Q> newNode(){     return new Node<Q>(); }  public static Node<String> newStringNode(String s){     return new Node<String>(s); } 

A simple narrative to the declaration may assist:

// This static method would have a <T> parameter to the class if it was not static public static <T>  // It returns an object of type `Node` with generic parameter T Node<T> newNode(){     // And here it is doing it's business.     return new Node<T>(); } 
like image 38
OldCurmudgeon Avatar answered Sep 19 '22 06:09

OldCurmudgeon