# Introduction to JSR-275: Measures and Units

Page 2
Page 2 of 4

## Class parameterization

Class parameterization is arguably the single most important enhancement to the Java platform since its infancy. The parameterized collection framework (`java.util.*`) demonstrates only a small fragment of what can be done through parameterization. The JScience project has pushed the envelope even further by taking advantage of parameterization in new areas such as mathematical structures (`Ring`, `Field`, `Group`), vectors/matrices and functions.

Parameterization has many advantages, not least being a "zero-cost at run time" because all the checks are done at compile time. JSR 275 takes advantage of class parameterization to ensure dimension consistency. As Listing 5 shows, classes such as `Measurable`, `Measure` and `Unit` are parameterized by their quantity type (such as `Mass` or `Length`). The dimensions of a unit (or measure) can be retrieved from the unit itself (at run time) of inferred from its quantity type (at compile time).

#### Listing 5. Parameterization for dimension consistency

``` ```Unit<length> inch = CENTI(METER).times(2.54); // OK.
Unit<length> inch = CENTI(LITER).times(2.54); // Compile error.

Measurable<Duration> d = Measure.valueOf(2, MINUTE); // OK.
Measurable<Duration> d = Measure.valueOf(2, WATT); // Compile Error.

long milliseconds = d.longValue(MILLI(SECOND)); // OK.
long milliseconds = d.longValue(MILLI(HERTZ)); // Compile error.```
```

When the compiler can't ensure commensurability, it issues a warning that can easily be removed through an explicit run-time check of the dimensions or by using the `?` wildcard parameterized type (see Listing 6).

#### Listing 6. Compiler warnings and how to remove them

``` ```// Compiler Warnings
Unit<Acceleration> mps2 = Unit.valueOf("m/s²"); // Compiler Warning.
Unit<Power> WATT = JOULE.divide(SECOND); // Compiler Warning.

// Adding run-time check of dimension consistency removes the warning.
Unit<Acceleration> mps2 = Unit.valueOf("m/s²").asType(Acceleration.class);
Unit<Power> WATT = JOULE.divide(SECOND).asType(Power.class);

// Use wildcard parameterized type (no warning and no check).
Unit<?> kelvinPerSec = KELVIN.divide(SECOND);```
```

## Units and units conversions

Units can be retrieved from constants held by various `SystemOfUnits` subclasses, such as `SI` (holding the "Système International d'Unités" standard units) or `NonSI` (holding nonstandard but common units). Custom systems of units can be created, and units can belong to several system of units. For example, the imperial system would contain many of the `NonSI` units. (You can use the `SystemOfUnits.getUnits()` member method to list all the units held by a system.)

`Measurable` or `Measure`?
`Measurable` is an interface allowing all kinds of implementations. It is basically equivalent to `java.lang.Number` and provides similarly named methods for conversion to primitive types (`intValue(Unit)`, `doubleValue(Unit)`). `Measure` is the simple combination of a numerical value and a unit. `Measurable` is more flexible, but if you need to retrieve the original numeric value stated in its original unit (no conversion), then `Measure` is your only choice.

By using predefined units, users avoid many conversion pitfalls. For example, the dry gallon is different from the liquid gallon, which is different in the United States and in the United Kingdom. Differentiation can be done either through `SystemOfUnits` (an imperial system would contain the U.K. units exclusively) or through distinct names such as `DAY_SIDEREAL` and `DAY_CALENDAR`, which differentiate between the day corresponding to the rotation of the Earth (23 hours, 56 minutes, 4.09 seconds) and the 24-hour calendar day. All conversion factors have been established from the latest Bureau International des Poids et Mesures (BIPM) standard.

If a unit does not exist in the `SI` or `NonSI` system of units, you can create new units by applying algebraic operations on existing units. Table 1 shows the operations supported on unit instances.

#### Table 1. Units operations

Result with same dimensionResult with different dimension
Binary operations:Binary operations:
`plus (double) or (long)``root (int)`
`times (double) or (long)``power (int)`
`divide (double) or (long)``times (Unit)`
`compound (Unit)``divide (Unit)`
Unary operations:
`inverse()`
Related:
Page 2
Page 2 of 4
``` ```
{"ft_lang_label":"__label__en","ft_lang_prob":0.8027466,"math_prob":0.8964439,"size":4217,"snap":"2020-24-2020-29","text_gpt3_token_len":952,"char_repetition_ratio":0.11227154,"word_repetition_ratio":0.0,"special_character_ratio":0.21555609,"punctuation_ratio":0.1352459,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9820157,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2020-06-02T01:16:39Z\",\"WARC-Record-ID\":\"<urn:uuid:b4942c9b-4fc8-42bd-8e32-dbb7eb529975>\",\"Content-Length\":\"132324\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:af48fa0c-b203-4bd8-9e47-c58926c7f093>\",\"WARC-Concurrent-To\":\"<urn:uuid:d2e5efe6-0169-43ec-9199-160f2efb1857>\",\"WARC-IP-Address\":\"151.101.250.165\",\"WARC-Target-URI\":\"https://www.javaworld.com/article/2077770/introduction-to-jsr-275--measures-and-units.html?page=2\",\"WARC-Payload-Digest\":\"sha1:MVFQ5BUYVEV27JSXA2KOS2HWICRCT3V6\",\"WARC-Block-Digest\":\"sha1:YIBBQQJ4Q2Q3CMLPHIEFCYKMTGASQKND\",\"WARC-Identified-Payload-Type\":\"application/xhtml+xml\",\"warc_filename\":\"/cc_download/warc_2020/CC-MAIN-2020-24/CC-MAIN-2020-24_segments_1590347422065.56_warc_CC-MAIN-20200602002343-20200602032343-00303.warc.gz\"}"}