Reputation: 1071
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 had never seen Java generic like
Value.<SomeValue>
The test is to implement Value class with the given unit test code above.
I tried to figure out the Value method signature below (need implementation):
public interface Value<T> {
public boolean hasValue();
public Value<T> createEmptyValue();
}
Any one know, please help?
Thank you
EDIT: Should be like this according to answers below @marlon
public class Value<T> {
public boolean hasValue(){}
public static <M> Value<M> createEmptyValue(){}; //need <M>
}
The key syntax to know:
Value.<SomeValue> //ClassName.<Type>method
is way to invoke static method of a class with parameterized argument.
EDIT: according to @snipes83, syntax to invoke non-static method of a class with parameterized argument.
SomeObject.<Type>method
Upvotes: 8
Views: 3843
Reputation: 13843
Value.<SomeValue>
it's the way generics are represented for methods.
Using Google Guava's Optional
as an example:
Optional<String> email = Optional.<String>of(strEmail);
See Generic Types - Invoking generic methods
Since interfaces cannot declare static methods (shame on you java), just declare your method as static and forget about the interface, like this:
class Value<T> {
public static <T> Value<T> createEmptyValue(){
return null;
}
}
Upvotes: 6
Reputation: 425198
Although Value
is itself obviously typed ( based on the instance variable type of Value<SomeValue>
), the static createEmptyValue()
method is also typed.
A reasonable assumption, if naming conventions have been adhered to, is that SomeValue
extends (or implements) Value
.
Although there us no one correct answer, a likely possibility for the signature of Value
is:
public class Value<T extend Value> {
public static <V extends Value> V createEmptyValue() {
// some impl
}
}
Upvotes: 1
Reputation: 15534
Look at the class Test
with the method getEmptyList
below:
public class Test {
public <T> List<T> getEmptyList() {
return new ArrayList<T>();
}
}
It returns an empty List
containing objects of type T
.
If you use Test
like this
Test t = new Test();
List<Integer> list = t.getEmptyList();
Then the type inference mechanism is able to infer the type parameter based on the variable type.
However if you need to use the return value of getEmptyList
within a method invocation expression like in the following example where the method printList
expects a single argument of type List<Integer>
, then the type can not be infered from any variable type.
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());
Upvotes: 3
Reputation: 2360
1) This is how generic methods are invoked. Refer >> http://docs.oracle.com/javase/tutorial/java/generics/methods.html
2) <SomeValue>
in Value.<SomeValue>
is optional. Compiler can infer the type. This is called TypeInference. Refer >> http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
Answer Updated:
3) Value.<SomeValue> createEmptyValue()
is right and Value.<SomeValue>createEmptyValue()
is right too. Both ways are legal. Just tested it. Didn't notice before.
Upvotes: 2