2

让我们想象一下:

public class Test
{
class A
{
    private String name = "toto";
    public String getId()
    {
        return name;
    }
}
class B
{
    int id = 99;
    public String getId()
    {
        return String.valueOf(id);
    }
}
public static void main(String[] args)
{
    Test t = new Test();

    A a = t.new A();
    B b = t.new B();

    List<A> list = new ArrayList<A>();
    list.add(a);
    list.add(a);
    list.add(a);

    List<?> genericList = list;

    for(Object obj : genericList)
        {
        System.out.println(obj.getId());
    }
}
}

System.out.println 编译时出错

The method getId() is undefined for the type Object

好的,这很正常。

但是我该怎么做才能让它工作呢?有没有可能有类似的东西

((obj.getClass().getSimpleName())obj).getId()
4

4 回答 4

4

我不确定你试图实现什么,但你为什么不使用接口:

interface IDHolder{

    String getId();
}

class A implements IDHolder{
    @Override
    String getId(){...}
}


class B implements IDHolder{
    @Override
    String getId(){...}
}

class Runner{
    List<? extends IDHolder> myObjectsWithIds = new ArrayList<>();
    A a = new A();
    B b = new B();
    myObjectsWithIds.add(a);
    myObjectsWithIds.add(b);
    for(IDHolder idHolder : myObjectsWithIds){
        idHolder.getId();
    }
}

如果您无法更改它们,请将它们包装起来:

class WrappedA implements IDHolder{
    private A a;

    public WrappedA(A a){
        this.a = a;
    } 
    @Override
    String getId(){
         return a.getId();
    }
}

class WrappedB implements IDHolder{
    private B b;

    public WrappedB(B b){
        this.b = b;
    } 
    @Override
    String getId(){
         return b.getId();
    }
}

class Runner{
    List<? extends IDHolder> myObjectsWithIds = new ArrayList<>();
    A a = new A();
    B b = new B();
    WrappedA wA = new WrappedA(a);
    WrappedB wB = new WrappedB(b);
    myObjectsWithIds.add(wA);
    myObjectsWithIds.add(wB);
    for(IDHolder idHolder : myObjectsWithIds){
        idHolder.getId();
    }
}
于 2013-05-24T12:10:00.127 回答
1

由于您无法更改课程,因此您有 2 个解决方案:

1)如果您确切知道您正在使用哪些类,请使用 instanceof (即使 instanceof 本身就是设计缺陷的证明......)

for(Object obj : genericList){
    if(obj instanceof A){
      System.out.println(((A)obj).getId());
    }
    if(obj instanceof B){
      System.out.println(((B)obj).getId());
    }
}

2)如果你根本不知道你的类,但知道它们必须有一个 getId() 方法,使用自省/反射来获取这个 getter

于 2013-05-24T12:29:59.790 回答
0

不,转换是使用固定的(在编译时)类完成的。事实上这就是它的想法,所以编译器知道(通过程序员干预)他正在处理哪个类(并且可以确保不调用不存在的方法)。

您可以使用反射从给定对象动态调用方法,但比这要复杂一些。

于 2013-05-24T12:06:23.113 回答
0

一个不错的方法是创建一个名为

public interface IdProvider {

  String getId();

}

制定AB实施它们

class A implements IdProvider
{
    private String name = "toto";
    public String getId()
    {
        return name;
    }
}
class B implements IdProvider
{
    int id = 99;
    public String getId()
    {
        return String.valueOf(id);
    }
}

并有一个通用的List<IdProvider>

List<IdProvider> list = new ArrayList<IdProvider>();
list.add(a);
list.add(a);
list.add(a);
list.add(b);
list.add(b);

for(IdProvider obj : genericList)
{
    System.out.println(obj.getId());
}
于 2013-05-24T12:11:03.350 回答