The meaning of Java Generics. <SomeValue>
I had an interview test and saw the following code:
EDIT:
public class TestValue { private Value<SomeValue> defaultValue; @Test public void Empty_Value_Has_No_Value() { Assert.assertFalse(Value.<SomeValue> createEmptyValue() .hasValue()); } @Test public void Default_Value_IsEmpty() { Assert.assertEquals(Value.<SomeValue> createEmptyValue(), defaultValue); } @Test public void Non_Empty_Value_Has_Value() { Assert.assertTrue(new Value<SomeValue>(true, new SomeValue()) .hasValue()); } } I've never seen java generic like
Value.<SomeValue> The test is to implement the Value class with the unit test code above.
I tried to find below the signature of the Value method (implementation needed):
public interface Value<T> { public boolean hasValue(); public Value<T> createEmptyValue(); } Does anyone know please help?
thanks
EDIT: should be like this, according to the answers below @marlon
public class Value<T> { public boolean hasValue(){} public static <M> Value<M> createEmptyValue(){}; //need <M> } Key Syntax:
Value.<SomeValue> //ClassName.<Type>method - a method of calling a static class method with a parameterized argument.
EDIT: according to @ snipes83, the syntax for calling a non-static class method with a parameterized argument.
SomeObject.<Type>method Value.<SomeValue> is how generic methods are represented for methods.
Using Google Guava Optional as an example:
Optional<String> email = Optional.<String>of(strEmail); See General Types - Calling General Methods
Since interfaces cannot declare static methods (shame on you java), just declare your method as static and forget about the interface, for example:
class Value<T> { public static <T> Value<T> createEmptyValue(){ return null; } } Look at the Test class using the getEmptyList method below:
public class Test { public <T> List<T> getEmptyList() { return new ArrayList<T>(); } } It returns an empty List object containing objects of type T
If you use Test like this
Test t = new Test(); List<Integer> list = t.getEmptyList(); Then the type inference engine can infer the type parameter based on the type of the variable.
However, if you need to use the getEmptyList return value in a method invocation expression, as in the following example, where the printList method expects a single argument of type List<Integer> , then the type cannot be inferred from any type of variable.
public void printList(List<Integer> list) { for (int i : list) { System.out.print(i); } } printList(t.getEmptyList()); // This will FAIL. In this case, you need to specify the type using the following:
printList(t.<Integer>getEmptyList()); 1) This is how generic methods are called. See → http://docs.oracle.com/javase/tutorial/java/generics/methods.html
2) <SomeValue> in Value.<SomeValue> optional . The compiler can infer the type. This is called TypeInference. See → http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
Answer Updated:
3) Value.<SomeValue> createEmptyValue() right and Value.<SomeValue>createEmptyValue() also right. Both methods are legal. Just tested it. Did not notice before.
Although Value itself is typed (based on the type of the instance variable Value<SomeValue> ), the static createEmptyValue() method is also introduced.
A reasonable assumption, if the naming conventions are followed, is that SomeValue extends (or implements) Value .
Although we do not have a single correct answer, a likely possibility for a Value signature is:
public class Value<T extend Value> { public static <V extends Value> V createEmptyValue() { // some impl } }