[英]Reflection in generic java class
I have followings classes (it's just a simplified example): 我有以下类(这只是一个简化的示例):
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();
}
}
The problem is indicated in the code. 该问题在代码中指出。
This is probably how I would have implemented it. 这可能就是我实施它的方式。 If it satisfactory or not for your situation, I can't tell. 如果对您的情况满意还是不满意,我不能告诉您。
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();
}
}
Here is one problem: 这是一个问题:
name
is instance method ( not static ), but you are trying to call it as static. name
是实例方法(不是static),但是您试图将其称为static。
This should fix it 这应该解决它
public class Car<T extends Material> {
public void printName( T material ) {
System.out.println( material.name());
}
/* ... */
}
问题是您试图在没有实例对象实例的情况下调用实例方法。
There are a lot of misunderstanding in your question: 您的问题有很多误解:
name()
is not a static function, therfore you need an instance of a material object to call it. name()
不是静态函数,因此需要材质对象的实例才能调用它。 name()
were static, you cannot call a static method from a generic name. 即使name()
是静态的,也不能从通用名称调用静态方法。 A solution? 一个解法? Create a enumeration of material: 创建材料的枚举:
public enum Material {
WOOD("wood"),
METAL("metal");
private final String name;
Material(String name) {
this.name = name;
}
}
And in the car class became: 在汽车课上变成了:
public class Car {
private final Material m;
public Car(Material m) {
this.m = m
}
public void printName() {
System.out.println(m.name);
}
/* ... */
}
T
defines the type, and the name()
should be static to be called in that context. T
定义类型,并且name()
应该是静态的,以便在该上下文中被调用。 Also, consider: 另外,请考虑:
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
}
/* ... */
}
This will never work, since your 'T' is only a "compiler hint", and you can't access the class defined by T at runtime, unless you refer to it explicitly in your functions. 这永远不会起作用,因为您的“ T”只是一个“编译器提示”,并且除非在函数中明确引用它,否则在运行时无法访问T定义的类。
That's not how java generics work: when you compile your code, any reference to Wood and Metal is lost, and your 2 "Car" objects are identical. 这不是java泛型的工作方式:编译代码时,对Wood和Metal的任何引用都会丢失,并且您的2个“ Car”对象是相同的。
Try this: 尝试这个:
myCar1 = new Car<Wood>();
System.out.println(myCar1 instanceof Car<Metal>);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.