2010-11-18 52 views
1

我有以下类(它只是一个简单的例子):反思通用的Java类

public abstract class Material { 
    public abstract String name(); 
    /* ... */ 
} 

public class Wood extends Material { 
    @Override 
    public String name() { 
     return "<WOOD>"; 
    } 
    /* ... */ 
} 

public class Metal extends Material { 
    @Override 
    public String name() { 
     return "{Metal}"; 
    } 
    /* ... */ 
} 

public class Car<T extends Material> { 
    public void printName() { 
     System.out.println(T.name()); // Here is the problem! 
    } 
    /* ... */ 
} 

public class Main { 
    public static void main(String[] args) { 
     Car<Wood> myCar1 = new Car<Wood>(); 
     Car<Metal> myCar2 = new Car<Metal>(); 
     myCar1.printName(); 
     myCar1.printName(); 
    } 
} 

问题是在代码中表示。

+0

我不认为这个问题有什么关系reflection.Please更改标题名称和标记。 – Emil 2010-11-18 12:07:17

回答

2

这里有一个问题:

name是实例方法(不是静态的),但你试图把它作为静态的。

这应该修复它

public class Car<T extends Material> { 
    public void printName(T material) { 
     System.out.println(material.name()); 
    } 
    /* ... */ 
} 
+2

没有,这不会工作...首先,你不能重写静态方法,所以这是没有道理的。 – aioobe 2010-11-18 12:06:52

+0

我真的想'名称'方法是'静态'。但如果不能,那么我不得不改造我的设计。非常感谢。 – barroco 2010-11-18 12:15:52

+1

但这不起作用。 'static'方法不是虚拟的,所以在这种情况下你总是会用'Material.name()'结束。 – aioobe 2010-11-18 12:18:16

1

的问题是,你要调用一个实例方法,而不必在其上称之为对象的实例。

1

在有你的问题是很多误解:

  1. name()不是一个静态的功能,therfore你需要的材料对象的实例来调用它。
  2. 即使name()是静态的,您不能从通用名称中调用静态方法。

解决方案?创建材料的枚举:

public enum Material { 
    WOOD("wood"), 
    METAL("metal"); 

    private final String name; 

    Material(String name) { 
     this.name = name; 
    } 
} 

而且在汽车类变成了:

public class Car { 
    private final Material m; 

    public Car(Material m) { 
     this.m = m 
    } 

    public void printName() { 
     System.out.println(m.name); 
    } 
    /* ... */ 
} 
0

T定义类型和name()应该是静态在这种情况下被调用。另外,考虑:

public class Car<T extends Material> { 
    protected T material; 
    // initialize material in constructor or wherever you want. 
    .... 
    public void printName() { 
     System.out.println(material.name()); // there is no problem 
    } 
    /* ... */ 
} 
3

这可能是我如何实现它。如果您的情况令人满意或不满意,我无法分辨。

enum Material { 

    WOOD("<WOOD>"), 
    METAL("{Metal}"); 

    String name; 
    private Material(String name) { 
     this.name = name; 
    } 
    public String toString() { 
     return name; 
    } 
} 

class Car { 
    Material material; 
    public Car(Material material) { 
     this.material = material; 
    } 
    public void printName() { 
     System.out.println(material); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     Car myCar1 = new Car(Material.WOOD); 
     Car myCar2 = new Car(Material.METAL); 
     myCar1.printName(); 
     myCar2.printName(); 
    } 
} 
0

这行不通,因为你的“T”仅仅是一个“暗示编译”,你不能在运行时访问的T定义的类,除非你在你的函数是指它明确。

这不是java泛型的工作方式:当你编译你的代码时,任何对Wood和Metal的引用都会丢失,而你的2个Car对象是相同的。

试试这个:

myCar1 = new Car<Wood>(); 
System.out.println(myCar1 instanceof Car<Metal>);