java - 使用 Java 派生类数组时出错

标签 java derived-class

我在这段代码中遇到了一个我不理解的错误(在注释中标记):

public class Symbol {
    private String name;
    public Symbol(String name) { this.name = name }
    public String name() { return name; }
}

public class Terminal extends Symbol {
    public Terminal(String name) { super(name); }
}

public class NonTerminal extends Symbol {
    public NonTerminal(String name) { super(name); }
}

public class Rule {
    private NonTerminal lhs;
    private Class<? extends Symbol>[] rhs;

    public Rule(NonTerminal lhs, Class<? extends Symbol>... rhs) {
        this.lhs = lhs;
        this.rhs = rhs;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(lhs.name());
        sb.append(" ->");
        for( int i = 0; i < rhs.length; i++ ) {
            sb.append(' ');
            sb.append(rhs[i].name()); <<<<< ERROR!
            // Get this error: The method name() is undefined for the type Class<capture#1-of ? extends Symbol>

            // Tried: sb.append(((Symbol)rhs[i]).name());
            // Got error: Cannot cast from Class<capture#1-of ? extends Symbol> to Symbol

        }
        sb.append(';');
        return sb.toString();
    }
}

该错误是由 Eclipse 中的 Java 编辑器给出的,而不是在编译时给出的。

换句话说:我希望能够获得符号列表,无论是终端还是非终端,并能够根据它们的类别使用它们。
到目前为止,我的理解是 Class<? extends Symbol>适用于 Symbol 类型的任何对象或源自Symbol

所以我的问题是:

  1. 为什么使用公共(public)方法name() ,在Symbol类中定义,无法调用。事实上列表中的所有元素都是符号或派生自符号?

  2. 调用 name() 的正确方法是什么?来自数组元素?

编辑 我稍微更正了代码,因此(根据接受的答案进行了更改)它是一个工作示例。这些变化是为了改变每一次出现的

Class<? extends Symbol>

Symbol

我用来检查答案的测试是:

    Terminal t1 = new Terminal("t1");
    Terminal t2 = new Terminal("t2");
    Terminal t3 = new Terminal("t3");

    NonTerminal exp = new NonTerminal("exp");
    NonTerminal nt1 = new NonTerminal("nt1");
    NonTerminal nt2 = new NonTerminal("nt2");
    NonTerminal nt3 = new NonTerminal("nt3");

    Rule r1 = new Rule(exp, t1, nt2, t3);

    Log.v(TAG, "The rule is: " + r1.toString());

日志文件显示:

01-15 10:18:11.335: V/MainActivity(1732): The rule is: exp -> t1 nt2 t3;

最佳答案

Class<? extends Symbol>是一个反射类 - 它存储类的定义,即 Symbol或其子类之一。

在您的示例中,您想要存储 Symbol实例 (或其子类之一)。只需像这样定义你的数组:

public class Rule {
    private NonTerminal lhs;
    private Symbol[] rhs;

    public Rule(NonTerminal lhs, Symbol... rhs) {
        this.lhs = lhs;
        this.rhs = rhs;
    }
}

关于java - 使用 Java 派生类数组时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21131589/

相关文章:

java - 如何从java类调用python脚本

java - Java中如何解析下面的json?我尝试使用简单的 json 但出现空指针异常

c++ - 扩展 boost::dynamic_bitset 以添加一些功能

c++ - 基类 -> 派生类和 C++ 中的反之转换

java - 可以同时运行maven1和maven2吗?

使用 testNG 调用测试时,不会反射(reflect)通过 ANT 初始化的 Java 变量

c++ - 如何重载和调用先前在其基类中定义的派生类中的方法?

c++ - 检查派生类类型

java: boolean instanceOf boolean 值?

java - JSON对象映射器: avoid listing derived class in serialized JSON string