我想要的是:
大多数情况下,泛型类将类似于TestBuilder<X, X>
,这意味着T和O属于同一类型。因此我创建了两个不同的构造函数。我想做一些像new TestBuilder<>(...)
这样的新调用(我在这里称<>
为无效)。
以下4个构造函数示例存在:
1)工作构造函数调用
// Anonoumous, working
new TestBuilder<>(String.class, Integer.class)
.withOnNext(new Action1<Integer>()
{
@Override
public void call(Integer integer)
{
}
});
// not anonoumous, classified, working
new TestBuilder<String, String>(String.class)
.withOnNext(new Action1<String>()
{
@Override
public void call(String string)
{
}
});
2)构造函数调用有问题或无法正常工作
// Anonoumous and working
// PROBLEM: withOnNext is called with Object instead of String
new TestBuilder<>(String.class)
.withOnNext(new Action1<Object>()
{
@Override
public void call(Object o)
{
}
});
// Anonoumous and NOT working
// this is what I want to work!
new TestBuilder<>(String.class)
.withOnNext(new Action1<String>()
{
@Override
public void call(String string)
{
}
});
问题
有没有办法让第4个构造函数工作?如果我只使用一个参数调用它,我不希望被强制给构造函数两个类,第二个泛型类应该在这种情况下从第一个继承“...而不是必须写new TestBuilder<String, String>(String.class)
我想写new TestBuilder<>(String.class)
或至少new TestBuilder<String>(String.class)
...
类
这是测试构建器类的样子:
public class TestBuilder<T, O>
{
public TestBuilder(Class<T> eventClass)
{
this(eventClass, (Class<O>)eventClass);
}
private TestBuilder(Class<T> eventClass, Class<O> observableClass)
{
init();
}
public TestBuilder<T, O> withOnNext(Action1<O> actionNext)
{
mActionNext = actionNext;
return this;
}
}
答案 0 :(得分:2)
我不认为Java可以在没有某种暗示的情况下推断出第二种通用类型。一种方法是在变量声明中给出类型:
TestBuilder<String, String> testBuilder = new TestBuilder<>(String.class);
testBuilder.withOnNext(new Action1<String>() {
@Override
public void call(String string) {
//...
}
});
但您仍需要声明两个通用参数。
我要做的是在静态工厂方法中封装T
和O
相同的信息:
public class TestBuilder<T, O> {
public static <T> TestBuilder<T, T> create(Class<T> eventClass) {
return new TestBuilder<T, T>(eventClass);
}
// ...
}
然后像这样调用它:
TestBuilder.create(String.class).withOnNext(...);
另一个选择是将信息封装在一个继承自TestBuilder
:
public class SimpleTestBuilder<T> extends TestBuilder<T,T> {
public SimpleTestBuilder(Class<T> eventClass) {
super(eventClass, eventClass);
}
}
public class TestBuilder<T, O> {
private TestBuilder(Class<T> eventClass, Class<O> observableClass) {
}
// ...
}
用作
new SimpleTestBuilder<>(String.class).withOnNext(...);
另一个好的选择是在静态方法中封装信息O
与T
相同:
public class TestBuilder<T, O> {
public static <T> TestBuilder<T, T> create(Class<T> eventClass) {
return new TestBuilder<T, T>(eventClass);
}
// ...
}
用作
TestBuilder.create(String.class).withOnNext(...);
答案 1 :(得分:0)
您可以为第一个构造函数引入一个帮助器类型变量,如下所示:
public class TestBuilder <T, O>
{
public <H extends T, O> TestBuilder(Class<H> c)
{
this((Class) c, (Class) c);
}
public TestBuilder(Class<T> c1, Class<O> c2)
{
// ...
}
public static void main(String[] args)
{
TestBuilder<String, String> hw = new TestBuilder<>(String.class);
System.out.println(hw);
}
}
这将为构造函数创建一些unchecked
警告,但不会在调用站点创建警告。请注意,虽然有些人可能会考虑这种广告实践,特别是因为不是每个人都知道构造函数类型参数。为了完整起见,构造函数的显式调用必须如下所示:
new<String> TestBuilder<>(String.class).doStuff()