多种返回类型和属性类型

时间:2020-08-25 06:26:09

标签: java generics wildcard return-type

我有以下课程

public class Expression<T> {
    private T expression;

    public Expression (T expression) {
        this.setExpression(expression);
    }

    // getters and setters
}

以及多种看起来像这样的类型

public class Load {
    private Variable memory;
    private Variable address;
    private long size;

    // constructor, getters and setters
}

和另一个同时使用表达式和变量的

public class Def {
    private Variable lhs;
    private Expression<?> rhs;

    public Def(Variable lhs, Expression<?> rhs) {
        this.setLhs(lhs);
        this.setRhs(rhs);
    }
}

现在,我想创建不同表达式类型的定义,例如Load,Store等。 但是,我只会在运行时知道它将是哪种类型的Expression,并且所有这些子类型仅存储变量,除了getter和setter之外,没有其他方法。

我有一个检查当前Expression类型是什么的函数,并且此函数有多个返回类型Expression。我无法弄清楚如何定义这样的功能。 这是一种尝试,但是,我只能扩展一个类:

protected Expression<? extends Load> createExpression(PcodeOp pcodeOp) {
    
    Varnode[] inputs = pcodeOp.getInputs();
    String mnemonic = pcodeOp.getMnemonic();
    
    if(mnemonic == "LOAD") {
        Expression<Load> loadExp = new Expression<Load>();
        return loadExp;
    } 
    else if(mnemonic == "STORE") {
        Expression<Store> storeExp = new Expression<Store>();
        return storeExp;
    }
    else if(mnemonic == "PIECE") {
        Expression<Concat> concatExp = new Expression<Concat>();
        return concatExp;
    }
    else if(mnemonic == "SUBPIECE") {
        Expression<Extract> extractExp = new Expression<Extract>();
        return extractExp;
    }
    else if(isBinOp(mnemonic)) {
        Expression<BinOp> binOpExp = new Expression<BinOp>();
        return binOpExp;
    }
    else if(isUnOp(mnemonic)) {
        Expression<UnOp> unOpExp = new Expression<UnOp>();
        return unOpExp;
    }
    else if(isCast(mnemonic)) {
        Expression<Cast> castExp = new Expression<Cast>();
        return castExp;
    }
}

此功能仍不完整,因为我仍然必须将所有变量添加到每种类型。

我对Java还是比较陌生,还没有找到其他好的实现。如果有人知道一种更好的实现方式,我很乐意听到。

2 个答案:

答案 0 :(得分:0)

您不能以“不错”且安全的方式进行此操作。因为您没有与warning msg.format关联的类型。但是,您可以做的就是向您的方法中添加一个通用参数:

PcodeOp

因此,当您调用该方法时,可以提供一种类型:

protected <T> Expression<T> createExpression(PcodeOp pcodeOp) {

但这就是您当前设置所能提供的全部功能。

答案 1 :(得分:0)

如果有人知道更好的实现方法,我很高兴听到这个消息

Enum<E…> 是否输入了您会考虑的内容?…

enum Mnemonic {
    
    LOAD, STORE, CONCAT( "PIECE" ), EXTRACT( "SUBPIECE" ) /* … */;
    
    …
}

如果是这样,则通用 Expression< … > 类的实验实现可能类似于...

class Expression< M extends Enum< M > > { 
    
    private M mnemonic;

    public Expression( M mnemonic ){ this.mnemonic = mnemonic; }
    
    …        
    
    /* other members elided */

}

实验 createExpression( … ) 可以简化为…

…
protected Expression< Mnemonic > createExpression( OpCode opCode ) { 

    switch( opCode.getMnemonic( ) ) { 
        
        case LOAD :
            return new Expression< Mnemonic >( LOAD );
            
        case STORE :
            return new Expression< Mnemonic >( STORE );
            
        case CONCAT :
            return new Expression< Mnemonic >( CONCAT );
            
        case EXTRACT :
            return new Expression< Mnemonic >( EXTRACT );
            
        /* … */
        
        default:
            return null;
    }
}

您可以observe an experimental run of this

…
Experiment experiment = new Experiment( );   
…
OpCode opCode = new OpCode( LOAD );
    
assertMnemonicEquals( opCode, LOAD );
…
assertMnemonicEquals( experiment.createExpression( opCode ), LOAD );
    
assertMnemonicEquals( experiment.createExpression( new OpCode( STORE ) ), STORE );
    
assertMnemonicEquals( experiment.createExpression( new OpCode( CONCAT ) ), CONCAT );
    
assertMnemonicEquals( experiment.createExpression( new OpCode( EXTRACT ) ), EXTRACT );
…

…导致…

EXPERIMENT SUCCESSFUL

此解决方案的另一个优势是可以有效地说服老板使用upgrade to JDK 14Switch Expression feature(现在是JDK 14 + 中的标准功能)将进一步提高此提议解决方案的效率和简便性。 the planned Pattern Matching feature可以进一步改善它。

相关问题