I have three different types of parameters: int, float and long. I want to use an object to represent each of them. So i have one abstract class:
abstract public class AbstractProtocolParamObj<T extends Number> { public enum ProtocolParamConstraintTypeEnum { None, OnOff, Values, ValueRange, ValueRangeIncrement } protected String name; protected ProtocolParamConstraintTypeEnum constraintValueType; protected Vector<AbstractProtocolParamObj<T>> dependentParams; protected Vector<AbstractProtocolParamObj<T>> constraintParams; protected T value; protected AbstractProtocolParamObj(String name, ProtocolParamConstraintTypeEnum constraintValueType, T value) { this.name = name; this.constraintValueType = constraintValueType; this.value = value; } public final String getName() { return name; } public final ProtocolParamConstraintTypeEnum getConstraintValueType() { return constraintValueType; } public void addDependentParam(AbstractProtocolParamObj<T> param) { if(dependentParams == null) { dependentParams = new Vector<AbstractProtocolParamObj<T>>(); } dependentParams.add(param); } public void addConstraintParam(AbstractProtocolParamObj<T> param) { if(constraintParams == null) { constraintParams = new Vector<AbstractProtocolParamObj<T>>(); } constraintParams.add(param); } public Vector<AbstractProtocolParamObj<T>> getDependentParams() { return dependentParams; } public Vector<AbstractProtocolParamObj<T>> getConstraintParams() { return constraintParams; } public T getValue() { return value; } public void setValue(T val) { value = val; } abstract public ReturnStatusEnum validate(T tempVal); } Then I will have one class for float parameters, one class for int and one for long. Like this:
public class ProtocolFloatParamObj extends AbstractProtocolParamObj { private float[] constraintVals; private float maxVal; private float minVal; private float increment; public ProtocolFloatParamObj(String name, float value, float[] constraintVals, ProtocolParamConstraintTypeEnum constraintType ) { super(name, constraintType, value); this.constraintVals = constraintVals; } public ProtocolFloatParamObj(String name, float value, float maxVal, float minVal, ProtocolParamConstraintTypeEnum constraintType ) { super(name, constraintType, value); this.maxVal = maxVal; this.minVal = minVal; } public ProtocolFloatParamObj(String name, float value, float maxVal, float minVal, float increment, ProtocolParamConstraintTypeEnum constraintType ) { this(name, value, maxVal, minVal, constraintType); this.increment = increment; } @Override public ReturnStatusEnum validate(Number val) { ReturnStatusEnum status = ReturnStatusEnum.SUCCESS; float tempVal = val.floatValue(); switch(constraintValueType) { case None: { break; } case OnOff: { break; } case Values: { break; } case ValueRange: { break; } case ValueRangeIncrement: { break; } } return status; } } Above code has no compile error but do has warnings which complain the generic type should be parameterized in subclass at the following lines:
public class ProtocolFloatParamObj extends AbstractProtocolParamObj super(name, constraintType, value); But if i change
public class ProtocolFloatParamObj extends AbstractProtocolParamObj to
public class ProtocolFloatParamObj <T extends Number> extends AbstractProtocolParamObj<T> and change the constructor value parameter from float to T. then everything looks good without compile error and warning.
The issue is because the ProtocolFloatParamObj constructor has a T parameter, its user/caller needs to define the T and it's easy to get warning or compile error.
For example in another class, I try to create a Vector contains some of those parameter objs but I cannot eliminate warnings or I cannot add to the objs vector:
public Vector<AbstractProtocolParamObj<T>> getAxialParamObjs() { Vector<AbstractProtocolParamObj<T>> objs = new Vector<AbstractProtocolParamObj<T>>(); ProtocolFloatParamObj<T> scanSpeed = new ProtocolFloatParamObj("scanSpeed", new Float(Float.parseFloat(m_axialDefaultConfig.getProperty("scanSpeed"))), new float[]{0.5f, 0.8f, 1.0f, 1.5f, 2.0f}, ProtocolParamConstraintTypeEnum.Values ); objs.add(scanSpeed); ...... return objs; } It seems this is not a good idea or i need read more about java generic.
Do you have a better idea and do you have any advanced java generic tutorial links?
ProtocolFloatParamObjshould extendAbstractProtocolParamObj<Float>.