Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'Subset' of Enum values in Java

Tags:

java

enums

I have a Java class that is something of the form:-

public class Angle
{
    ANGLE_TYPE angleType;

    ANGLE_TYPE defaultAngleType = ANGLE_TYPE.RAD;

    enum ANGLE_TYPE
    {
        DEG, RAD, DEGMIN, DEGMINSEC;
    }
}

The class has an 'enum' defined, as can be seen. My question regards the instance variable, 'defaultAngleType'. I want it to be the case so that this variable can only be assigned the values RAD or DEG, and to throw an error otherwise.

Any idea how to acheive this?

like image 548
Jeremy Watts Avatar asked Sep 09 '15 12:09

Jeremy Watts


Video Answer


4 Answers

Probably the enum is not the best structure to use for this.

I'd apply some inheritance-based approach.

interface Angle { }
class DegMin implements Angle { }
class DegMinSec implements Angle { }

interface SpecialAngle extends Angle { } 
class Deg implements SpecialAngle { }
class Rag implements SpecialAngle { }

Having this hierarchy, all of the classes are Angle(s), but only two of them are SpecialAngle(s) (Deg and Rad).

Then, in your class, you'd have:

public class Angle
{
    Angle angleType;

    SpecialAngle defaultAngleType = new Rad();
}

Now defaultAngleType can only hold instances of Rad or Deg.

like image 136
Konstantin Yovkov Avatar answered Oct 27 '22 09:10

Konstantin Yovkov


You can use an EnumSet. For example:

Set<ANGLE_TYPE> allowed = EnumSet.of(RAD, DEG);
like image 25
omerkudat Avatar answered Oct 27 '22 09:10

omerkudat


Make defaultAngleType private. In the setter for defaultAngleType, check the argument, and do something like:

public void setDefaultAngleType(ANGLE_TYPE type){
    if(type.equals(DEG) || type.equals(RAD))
        defaultAngleType = type;
    else
        throw new Exception();
}
like image 28
mattm Avatar answered Oct 27 '22 09:10

mattm


Make the constructor of Angle private, and only allow its creation through static factory methods:

private Angle(ANGLE_TYPE type, float value) {
   //...
}

static Angle degrees(float value) {
  return new Angle(ANGLE_TYPE.DEG, value);
}

static Angle radians(float value) {
  return new Angle(ANGLE_TYPE.RAD, value);
}

This means that trying to create one of the others becomes a compile-time error, rather than a runtime error.

Of course, you need to control access to the angleType variable by making it private and providing a getter, because you can't otherwise stop somebody changing the field to one of the forbidden values.

like image 40
Andy Turner Avatar answered Oct 27 '22 08:10

Andy Turner