Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有泛型静态工厂的Java泛型拼图器_Java_Generics - Fatal编程技术网

带有泛型静态工厂的Java泛型拼图器

带有泛型静态工厂的Java泛型拼图器,java,generics,Java,Generics,我最近开始为一个项目编写一个通用对象映射程序,但遇到了一些我不太理解的问题。鉴于以下情况: public class G<X> { public G(Class<X> c) { } public void m(X x) { } public static <T> G<T> create(Class<T> c) { return new G<T>(c); } public static voi

我最近开始为一个项目编写一个通用对象映射程序,但遇到了一些我不太理解的问题。鉴于以下情况:

public class G<X> {
  public G(Class<X> c) { }

  public void m(X x) { }

  public static <T> G<T> create(Class<T> c) {
    return new G<T>(c);
  }

  public static void main(String[] args) {
    Object o = ""; // irrelevant!
    G<?> t = create(o.getClass());
    t.m(o);
  }
}
inconvertible types
found   : G<capture#155 of ? extends java.lang.Object,Y<capture#155 of ? extends java.lang.Object>>
required: G<java.lang.Object,Y<java.lang.Object>>
如果我将泛型对象类传递给
create
,这似乎会中断

请注意,我的实际实现将所有
FooDTO
类从一个泛型超类扩展而来,即
Mapper
的签名实际上类似于
Mapper
。我认为这与这里无关

编辑2

实际上,建议更改行
gt=create(o.getClass())
to
gt=(G)创建(o.getClass())在这个上下文中工作

不幸的是,我没有意识到我的类更复杂这一事实实际上会产生影响。这里有一个更完整的例子(我为这个零碎的问题道歉):

公共类Y{
}
公共类别G{
公共G类(c类、s类){
}
公共空间m(X X){
}
公共静态G创建(c类){
类s=null;//通过某种反射魔法找到它
返回新的G(c,s);
}
公共静态void main(字符串[]args){
对象o=”“;//不相关!

G您已经从传递了
Class
对象,该对象返回一个
Class
,这意味着您必须声明
t
G

当变量的泛型类型参数是通配符时,不能使用泛型类型参数调用方法。编译器不知道通配符真正是哪个特定类,因此在调用此类方法时无法保证类型安全。这与不能在
列表上调用
add
的原因相同

要编译它,必须使用类文字,以避免使用
class
,并声明
t
没有通配符

G<Object> t = create(Object.class);

将编译。

由于您指定的是
G
,javac希望找出泛型是什么(它们代表什么类)。将语句更改为
gt=create(o.getClass());
修复错误

capture
错误通常意味着编译器无法找出类


现在还不清楚您想做什么……也许这些信息对您的帮助更大……

您正在创建一个
G
,然后将其分配给
G
类型的变量。调用的方法将使用泛型类型的变量,而
不会接受任何内容。如果您将该变量更改为
G
它会起作用。

您这里有一个消费者

公共静态类G{

公共G(类)你想实现什么?让我再添加一些评论。用G@sinelaw没有区别。我不认为简单地将
G
更改为
G
编译。由于
G
的构造函数的编写方式,
create(o.getClass())
正在创建一个实际有效的
。不过我有一个跟进。更改我的SO。如果我不知道类型,并且只有一个对象的引用怎么办?这就是我的全部问题。如果我传递
object.class
我会丢失所有运行时类型信息。删除泛型并不能解决问题,它只会将其清除地毯。是的,编译器无法识别类型,但删除泛型会删除泛型类型安全性,因此编译器甚至没有机会。但这完全改变了类。构造函数选择
class
的唯一原因可能是因为将
x
传递给
.m()很重要
是该类的一个实例。如果您将其更改为
ClassAccepting,因为在我的情况下,它工作得很好。如果我发现一个案例出现问题,我将更新我的问题。@newacct,您是对的,这会更改类
G
,但请考虑一下:您始终可以传递扩展
X
mx
不是该类的一个实例。我的意思是,将类型为
class
的类
c
传递到
G
的构造函数中有什么意义?OP的代码不显示该类中的任何代码,所以从字面上看,我们可以删除该p参数。但是人们会猜测,类
c
G
的第一个类型参数匹配有一些要求。特别是,类型
X
用于另一个地方:方法
m
中的参数
X
的类型。因此,可以合理地想象,在
m
必须是
c
的一个实例。在实践中,
c
参数很可能来自
getClass()
m()
的参数上调用的
getClass()
,但编译器在此呈现中无法保证这一点。
public class Y<T> {
}

public class G<X, Z extends Y<X>> {
  public G(Class<X> c, Class<Z> s) {
  }

  public void m(X x) {
  }

  public static <T, S extends Y<T>> G<T, S> create(Class<T> c) {
    Class<S> s = null; // find this via some reflection magic
    return new G<T, S>(c, s);
  }

  public static void main(String[] args) {
    Object o = ""; // irrelevant!
    G<? extends Object, Y<? extends Object>> t = create(o.getClass());
    t.m(o);
  }
}
inconvertible types
found   : G<capture#155 of ? extends java.lang.Object,Y<capture#155 of ? extends java.lang.Object>>
required: G<java.lang.Object,Y<java.lang.Object>>
G<Object, Y<Object>> t = (G<Object, Y<Object>>) create(o.getClass());
java: inconvertible types
required: G<java.lang.Object,Y<java.lang.Object>>
found:    G<capture#1 of ? extends java.lang.Object,Y<capture#1 of ? extends java.lang.Object>>
G<Object> t = create(Object.class);
t.mo(o);
public static class G<X, Z extends Y<X>> {
    public G(Class<? extends X> c, Class<Z> s) {}
    public void m(X x) {}
    public static <T, S extends Y<T>> G<T, S> create(Class<? extends T> c) {
        Class<S> s = null; // find this via some reflection magic
        return new G<T, S>(c, s);
    }
    public static void main(String[] args) {
        Object o = ""; // irrelevant!
        create(o.getClass()).m(o);
    }
}