Java&转换通用对象

时间:2013-05-24 12:03:48

标签: java casting

让我们想象一下:

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 个答案:

答案 0 :(得分: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();
    }
}

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

您可以使用反射来动态调用给定对象的方法,但它比这更复杂。

答案 3 :(得分: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());
}