A simple Java unit library to provide compile-time safety for units. No more of this:
double distance = 12.34; // What unit is this?
Now you can have this:
Measure<Distance> distance = Units.Inches.of(12.34); // It has to be inches!
And since Inches
is a built-in unit, we can use a special subclass of Measure<Distance>
Inches distance = Inches.of(12.34);
Note that this Inches
class is not the same thing as Units.Inches
Of course, units can be converted from one type to another, as long as they measure the same kind of thing!
void doSomething(Measure<Distance> distance) {
// Convert the distance to some known type that this class can use
double inches = distance.as(Units.Inches);
// ...
}
This library has many common units, but sometimes you just want to use furlongs or stone:
Unit<Distance> Furlongs = Units.Feet.aggregate(660);
Unit<Mass> Stone = Units.Pounds.aggregate(14);
Unit<Mass> Milligram = Units.Grams.splitInto(1000);
unit.aggregate(n)
creates a new unit that is equivalent to n of the original unit; the new unit is the "aggregate" of n of the original unit
unit.splitInto(n)
is the reverse; it creates a new unit that is equivalent to 1 / n of the original unit (the original unit is "split into" n equal parts, each of which is equal to 1 of the resulting unit)
For example,
Unit kilo = someUnit.aggregate(1000);
Unit milli = someUnit.splitInto(1000);
interface Gyro {
Measure<Angle> getAngle();
}
Gyro gyro = ...
Measure<Angle> angle = gyro.getAngle();
Generally, if you want to declare some constant measure (such as a target angle or distance), those should be declared using the specialized measure classes, eg Inches targetDistance = Inches.of(...)
. This makes the code much clearer since the unit is determinable just by looking at the left-hand side of the declaration.
If you're just grabbing the output of a sensor and passing that to something that consumes that kind of measure (e.g. reading a voltage from an analog sensor and passing that to a motor), then it's okay to use a generic Measure<ElectricPotential> sensorOutput = mySensor.getRawVoltage()