我进行了面试测试并看到了以下代码:
编辑:
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());
}
}
我从未见过像Java一样的通用
Value.<SomeValue>
测试是使用上面给定的单元测试代码实现Value类。
我试图找出下面的Value方法签名(需要实现):
public interface Value<T> {
public boolean hasValue();
public Value<T> createEmptyValue();
}
任何人都知道,请帮帮忙?
谢谢
编辑:根据@marlon 下面的答案,应该是这样的public class Value<T> {
public boolean hasValue(){}
public static <M> Value<M> createEmptyValue(){}; //need <M>
}
要知道的关键语法:
Value.<SomeValue> //ClassName.<Type>method
是使用参数化参数调用类的静态方法的方法。
编辑:根据@ snipes83,使用参数化参数调用类的非静态方法的语法。
SomeObject.<Type>method
答案 0 :(得分:6)
Value.<SomeValue>
这就是为方法表示泛型的方式。
以Google Guava的Optional
为例:
Optional<String> email = Optional.<String>of(strEmail);
请参阅Generic Types - Invoking generic methods
由于接口不能声明静态方法(对java很遗憾),只需将方法声明为静态并忘记接口,如下所示:
class Value<T> {
public static <T> Value<T> createEmptyValue(){
return null;
}
}
答案 1 :(得分:3)
使用以下方法Test
查看课程getEmptyList
:
public class Test {
public <T> List<T> getEmptyList() {
return new ArrayList<T>();
}
}
它返回一个空List
个包含T
类型的对象。
如果你这样使用Test
Test t = new Test();
List<Integer> list = t.getEmptyList();
然后类型推断机制能够根据变量类型推断出类型参数。
但是,如果您需要在方法调用表达式中使用getEmptyList
的返回值,例如以下示例中方法printList
需要单个List<Integer>
类型的参数,那么不能从任何变量类型中输入类型。
public void printList(List<Integer> list) {
for (int i : list) {
System.out.print(i);
}
}
printList(t.getEmptyList()); // This will FAIL.
在这种情况下,您需要使用以下内容指定类型:
printList(t.<Integer>getEmptyList());
答案 2 :(得分:2)
1)这是调用泛型方法的方法。参考&gt;&gt; http://docs.oracle.com/javase/tutorial/java/generics/methods.html
<SomeValue>
中的 2) Value.<SomeValue>
可选。编译器可以推断出类型。这称为 TypeInference 。参考&gt;&gt; http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
答案已更新:
3) Value.<SomeValue> createEmptyValue()
是对的,Value.<SomeValue>createEmptyValue()
也是对的。两种方式都是合法的。刚试过它。之前没有注意到。
答案 3 :(得分:1)
虽然Value
本身显然是键入的(基于Value<SomeValue>
的实例变量类型),但也会键入静态createEmptyValue()
方法。
如果遵守命名约定,则合理的假设是SomeValue
扩展(或实现)Value
。
虽然我们没有正确答案,但Value
签名的可能性很可能是:
public class Value<T extend Value> {
public static <V extends Value> V createEmptyValue() {
// some impl
}
}