2013-11-21 57 views
1


我有一个我想与任何一个Stringint值来实例化一个类,我定义了相应的实例变量value为通用型T是否可以使用特定类型的值初始化泛型变量?

public class MathValue<T extends Object> { 
    private boolean isOperand, isOperator; 

    // a generic-typed instance variable: 
    private T value; 

    // constructor: 
    public MathValue(int operand) { 

     // compile-error -- "Incompatible types: required T, found Integer" 
     this.value = new Integer(operand); 

     this.isOperand = true; 
     this.isOperator = false; 
    } 

    // constructor: 
    public MathValue(String operator) { 

     // compile-error -- "Incompatible types: required T, found String" 
     this.value = operand; 

     this.isOperand = false; 
     this.isOperator = true; 
    } 
} 


非常好有一个单一的构造函数,具有T类型的形式参数,但我想强制类的实例化,使用Stringint参数:

public class MathValue<T extends Object> { 
    private boolean isOperand, isOperator; 

    // a generic-typed instance variable: 
    private T value; 

    // it totally works, but does not enforce specific-typed instantiation: 
    public MathValue(T operandOrOperator) { 
     this.value = operandOrOperator; 

     if (operandOrOperator instanceof Integer) { 
      this.isOperand = true; 
      this.isOperator = false; 

     } else if (operandOrOperator instanceof String) { 
      this.isOperand = false; 
      this.isOperator = true; 
     } 
    } 
} 


所以尽管想使一个通用的类型类“不那么通用”的逻辑错误,是否有可能来实例化一个普通变量与特定类型的值?

+0

'T延伸TheSpecificTypesMustUnifyHere'。 – user2864740

+3

我不认为这是可能的,因为'String'和'Integer'在不同的类型层次结构中,只有普通的超类型是'Object'。但是你可以做的是,如果'T'不是它们中的任何一个的实例,则从构造函数中抛出一个未经检查的异常。 –

+0

啊,谢谢@RohitJain,好主意! –

回答

1

您可以创建工厂方法。这里现在看起来可能:

public class MathValue<T extends Object> { 

    public static MathValue<String> from(String s) { 
     MathValue<String> mv = new MathValue<String>(); 

     mv.setValue(s); 
     mv.setIsOperand(true); 
     return mv; 
    } 

    public static MathValue<Integer> from(Integer s) { 
     MathValue<Integer> mv = new MathValue<Integer>(); 

     mv.setValue(i); 
     mv.setIsOperand(false); 
     return mv; 
    } 

    // Rest of your class below 
} 

如果你绝对需要一个构造函数(例如,你不知道,你正在创建的时间提前的类型),那么我看不到周围的方式@ RohitJain的建议。

+0

真棒,感谢@bstempi的信息!对于这样的问题,这可能是一种常见的设计模式吗? –

+2

这是[静态工厂模式](http://stackoverflow.com/questions/929021/what-are-static-factory-methods-in-java)。这里适用,因为你有一些你关心的特定类型的T。一般来说,如果你有一些'T'类型来处理,这是一个糟糕的方法。 – bstempi

1

你可以使用子类。定义一个抽象类来实际存储的值,一般地:

abstract class MathValue<T> { 
     private final T value; 

     MathValue(T value) { 
       this.value = value; 
     } 

     abstract boolean isOperator(); 

     boolean isOperand() { 
       return !isOperator(); 
     } 
} 

接着一个子类,强制值类型是一个整数。

class OperandValue extends MathValue<Integer> { 

     OperandValue(int operand) { 
       super(new Integer(operand)); 
     } 

     @Override 
     public boolean isOperator() { 
       return false; 
     } 
} 

和另一个强制它为String的子类型。

class OperatorValue extends MathValue<String> { 

     OperatorValue(String operator) { 
       super(operator); 
     } 

     @Override 
     boolean isOperator() { 
       return true; 
     } 
} 

有了这个设计,您实际上并不需要存储布尔值。

(注意,为了简单起见,我离开了可视性关键字)。

+0

奇妙的是,不知道你可以专门在一个子类中的泛型打字,很酷的东西! –

相关问题