Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
泛型java类中的反射_Java_Generics_Reflection - Fatal编程技术网

泛型java类中的反射

泛型java类中的反射,java,generics,reflection,Java,Generics,Reflection,我有以下课程(这只是一个简单的例子): 公共抽象类材料{ 公共抽象字符串名称(); /* ... */ } 公共级木材材料{ @凌驾 公共字符串名称(){ 返回“”; } /* ... */ } 公共级金属材料{ @凌驾 公共字符串名称(){ 返回“{Metal}”; } /* ... */ } 公车{ public void printName(){ System.out.println(T.name());//问题出在这里! } /* ... */ } 公共班机{ 公共静态void main

我有以下课程(这只是一个简单的例子):

公共抽象类材料{
公共抽象字符串名称();
/* ... */
}
公共级木材材料{
@凌驾
公共字符串名称(){
返回“”;
}
/* ... */
}
公共级金属材料{
@凌驾
公共字符串名称(){
返回“{Metal}”;
}
/* ... */
}
公车{
public void printName(){
System.out.println(T.name());//问题出在这里!
}
/* ... */
}
公共班机{
公共静态void main(字符串[]args){
汽车myCar1=新车();
汽车myCar2=新车();
myCar1.printName();
myCar1.printName();
}
}
代码中指出了问题。

这里有一个问题:

name
是实例方法(不是静态的),但您试图将其称为静态的

这应该可以解决它

public class Car<T extends Material> {
    public void printName( T material ) {
        System.out.println( material.name()); 
    }
    /* ... */
}
公车{
公共无效打印名(T物料){
System.out.println(material.name());
}
/* ... */
}
这里有一个问题:

name
是实例方法(不是静态的),但您试图将其称为静态的

这应该可以解决它

public class Car<T extends Material> {
    public void printName( T material ) {
        System.out.println( material.name()); 
    }
    /* ... */
}
公车{
公共无效打印名(T物料){
System.out.println(material.name());
}
/* ... */
}

问题在于,您试图调用实例方法时,没有对象的实例可供调用。

问题在于,您试图调用实例方法时,没有对象的实例可供调用。

您的问题中有很多误解:

  • name()
    不是静态函数,因此需要材质对象的实例来调用它
  • 即使
    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);
        }
        /* ... */
    }
    

    你的问题中有很多误解:

  • name()
    不是静态函数,因此需要材质对象的实例来调用它
  • 即使
    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);
        }
        /* ... */
    }
    

    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
        }
        /* ... */
    }
    
    公车{
    受保护的T材料;
    //在构造器中或任何您想要的地方初始化材质。
    ....
    public void printName(){
    System.out.println(material.name());//没有问题
    }
    /* ... */
    }
    
    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
        }
        /* ... */
    }
    
    公车{
    受保护的T材料;
    //在构造器中或任何您想要的地方初始化材质。
    ....
    public void printName(){
    System.out.println(material.name());//没有问题
    }
    /* ... */
    }
    
    我可能就是这样实现它的。如果对你的情况满意与否,我不能说

    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();
        }
    }
    
    enum材质{
    木头(“”),
    金属(“{METAL}”);
    字符串名;
    私有材料(字符串名称){
    this.name=名称;
    }
    公共字符串toString(){
    返回名称;
    }
    }
    班车{
    材料;
    公共汽车(材料){
    这个材料=材料;
    }
    public void printName(){
    系统输出打印项次(物料);
    }
    }
    公共班机{
    公共静态void main(字符串[]args){
    Car myCar1=新车(材料:木材);
    汽车myCar2=新车(材料、金属);
    myCar1.printName();
    myCar2.printName();
    }
    }
    
    我可能就是这样实现它的。如果对你的情况满意与否,我不能说

    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();
        }
    }
    
    enum材质{
    木头(“”),
    金属(“{METAL}”);
    字符串名;
    私有材料(字符串名称){
    this.name=名称;
    }
    公共字符串toString(){
    返回名称;
    }
    }
    班车{
    材料;
    公共汽车(材料){
    这个材料=材料;
    }
    public void printName(){
    系统输出打印项次(物料);
    }
    }
    公共班机{
    公共静态void main(字符串[]args){
    Car myCar1=新车(材料:木材);
    汽车myCar2=新车(材料、金属);
    myCar1.printName();
    myCar2.printName();
    }
    }
    
    这永远不会起作用,因为您的“T”只是一个“编译器提示”,您不能在运行时访问由T定义的类,除非您在函数中显式引用它

    java泛型不是这样工作的:当您编译代码时,对Wood和Metal的任何引用都会丢失,并且您的两个“Car”对象是相同的

    试试这个:

    myCar1 = new Car<Wood>();
    System.out.println(myCar1 instanceof Car<Metal>);
    
    myCar1=新车();
    System.out.println(myCar1 Car实例);
    
    这永远不会起作用,因为您的“T”只是一个“编译器提示”,您不能在运行时访问由T定义的类,除非您在函数中显式引用它

    java泛型不是这样工作的:当您编译代码时,对Wood和Metal的任何引用都会丢失,并且您的两个“Car”对象是相同的

    试试这个:

    myCar1 = new Car<Wood>();
    System.out.println(myCar1 instanceof Car<Metal>);
    
    myCar1=新车();
    System.out.println(myCar1 Car实例);
    
    不,那不行。。。首先,你不能覆盖静态方法,所以这没有意义。我真的希望'name'方法是
    static
    。但如果不行,我就得重新设计我的设计。非常感谢。但这行不通<代码>静态方法不是虚拟的,因此在这种情况下,您总是会得到
    Material.name()
    。不,这不起作用。。。首先,你不能覆盖静态方法,所以这没有意义。我真的希望'name'方法是
    static
    。B