Java泛型类型继承错误

Java泛型类型继承错误,java,generics,inheritance,Java,Generics,Inheritance,在Android Studio中,我有以下错误: java:不兼容的类型:java.lang.Object无法转换为 java.lang.String 我认为b1和b2的行为应该相同,但事实并非如此 有没有办法让他们表现得一样(不改变他们的课程类型) 以下是键入的代码: public class Test { class A<T> { T t; T getT() { return t;

在Android Studio中,我有以下错误:

java:不兼容的类型:java.lang.Object无法转换为 java.lang.String

我认为b1和b2的行为应该相同,但事实并非如此

有没有办法让他们表现得一样(不改变他们的课程类型)

以下是键入的代码:

public class Test
{
    class A<T>
    {
        T t;
        T getT()
        {
            return t;
        }
    }
    class AS extends A<String>
    {

    }
    class B<T> extends AS
    {

    }

    B<Object> b1;
    B b2;

    public void test()
    {
        String t3 = b1.getT();
        String t4 = b2.getT();
    }
}
公共类测试
{
甲级
{
T;
T getT()
{
返回t;
}
}
类作为扩展
{
}
B类扩展为
{
}
B b1;
B b2;
公开无效测试()
{
字符串t3=b1.getT();
字符串t4=b2.getT();
}
}

这里的问题是
getT()
返回对象。您需要做的是实现一个方法
toString()
,它以
字符串的形式给出
T
对象的值(或者只需将
t3
t4
的类型更改为
T
,这样声明就变成了
t3=b1.getT();
t4=b2.getT();

此外,您应该执行以下操作,而不是执行针对B的代码

B<T> b1;
B<T> b2;
b1;
B b2;

请注意,在调用
b1.anyMethod()
之前,需要将B初始化为某个值,否则会出现
空指针异常

我认为没有模板对象的
B
是一个不完整的类,而不是
B
。这就是为什么当您调用它时,实际上是在调用A.getT()

这就是为什么在下面的代码中,只有
stringt3=b2.getT()无法编译

static class A<T>
{
    T t;
    T getT()
    {
        return t;
    }
}

static class AS extends A<String> {}

static class B<T> extends AS {}

static class C extends B<Object> {}

static A a;
static B<Object> b1 = null;
static B b2 = new B();
static C c = new C();

static void test()
{
    Object tt = a.getT();
    String t2 = b1.getT();
    String t3 = b2.getT();
    String t4 = c.getT();
}
静态A类
{
T;
T getT()
{
返回t;
}
}
静态类扩展为{}
静态类B扩展为{}
静态类C扩展了B{}
静态A;
静态B b1=零;
静态B b2=新的B();
静态C=新C();
静态孔隙试验()
{
对象tt=a.getT();
字符串t2=b1.getT();
字符串t3=b2.getT();
字符串t4=c.getT();
}

问题在于
B
是一个参数化类型,但是
b2
被声明为将原始
B
作为其类型

使用
b1
演示
B
的类型参数与
A
不同,即使它们具有相同的名称,因此B的类型参数与继承自
A
getT()
方法的返回类型无关。但是,当您使用原始类型时,您可以完全擦除该类型,包括其超类型

由于的
A
的类型参数是无界的,因此它的擦除将生成类型
对象
,因此这是
b2.getT()
的类型。当然,
对象
不能分配给
字符串

您至少可以通过两种方式解决此问题:

  • 不要将原始类型用于
    b2
    。如果不关心其类型参数,则使用
    B
    。或者

  • 删除class
    B
    的类型参数。在您的示例中,它没有用于任何内容,因此这将是最干净的做法。仅仅因为它的超类是泛型的,并不意味着
    B
    必须是泛型的


  • 你能复制并粘贴代码,这样我就可以为我的答案抓取代码样本吗?我已经编辑了我的答案,所以代码是可复制的。:)更正,可以用
    javac
    复制,但不能用
    eclipsec
    复制。但逻辑是一样的;您使用已擦除版本的
    B
    ,您使用已擦除版本的
    A
    ,因此它将根据返回一个对象。这毕竟是一个骗局。事实上,这不会导致OP描述的错误,尽管这会在OP修复当前错误后导致错误。我不明白你的意思,@PMARINA。您是否不同意在OP的代码中,
    b2.getT()
    的返回类型是
    Object
    ?然后,您将很难解释编译器错误。或者你不同意我对原因的解释?如果是这样,请分享。请确保您可以解释为什么
    b1.getT()
    会返回
    String
    ,但是,当
    b1
    的类型为
    B
    时。我不同意您的回答,即当前错误是由参数引起的。问题是调用getT()应该返回类型为T的对象。这不应该通过始终让输入类型为string来解决。相反,OP应该添加一个toString()方法并调用它,而不是getT()。您总是使用字符串的解决方案是愚蠢的,因为OP不需要额外的类来单独使用字符串,除非他/她计划使用其他数据类型,否则不会将其命名为t()。@PMARINA,您的观点与可观察到的事实相矛盾。OP的
    b1.getT()
    返回一个
    字符串
    ,即使
    b1
    已声明类型
    B
    。您可以通过自己的编译器自己验证这一点。我想这就是OP在他的例子中包含它的原因。这是因为类
    B
    继承了特定的实现
    A
    ,而不是像通常那样继承
    A
    <因此,正如我在回答中所解释的那样,code>B
    的类型参数与
    A
    无关。谢谢大家的帮助!:)我不知道这种“原始类型”。)我想你没抓住重点。这里的基本问题是,为什么在
    b2
    (类型
    B
    )上调用
    getT()
    时返回
    Object
    ,即使在
    b1
    (类型
    B
    )上调用时返回
    String
    )。重写
    toString()
    的建议是不正确的;没有理由认为它是所需的其他类型对象的字符串表示形式。