0
# Units Annotations
1
2
Units annotations provide dimensional analysis and physical unit checking to prevent unit conversion errors and ensure dimensional consistency in calculations involving physical quantities.
3
4
## Capabilities
5
6
### Base Physical Units
7
8
Annotations for fundamental SI base units.
9
10
```java { .api }
11
/**
12
* Length measurement (base unit: meter)
13
*/
14
@Documented
15
@Retention(RetentionPolicy.RUNTIME)
16
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
17
@UnitsRelations(org.checkerframework.checker.units.qual.m.class)
18
public @interface Length {}
19
20
/**
21
* Mass measurement (base unit: kilogram)
22
*/
23
@Documented
24
@Retention(RetentionPolicy.RUNTIME)
25
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
26
@UnitsRelations(org.checkerframework.checker.units.qual.kg.class)
27
public @interface Mass {}
28
29
/**
30
* Time measurement (base unit: second)
31
*/
32
@Documented
33
@Retention(RetentionPolicy.RUNTIME)
34
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
35
@UnitsRelations(org.checkerframework.checker.units.qual.s.class)
36
public @interface Time {}
37
38
/**
39
* Electric current (base unit: ampere)
40
*/
41
@Documented
42
@Retention(RetentionPolicy.RUNTIME)
43
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
44
@UnitsRelations(org.checkerframework.checker.units.qual.A.class)
45
public @interface Current {}
46
47
/**
48
* Temperature (base unit: kelvin)
49
*/
50
@Documented
51
@Retention(RetentionPolicy.RUNTIME)
52
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
53
@UnitsRelations(org.checkerframework.checker.units.qual.K.class)
54
public @interface Temperature {}
55
56
/**
57
* Amount of substance (base unit: mole)
58
*/
59
@Documented
60
@Retention(RetentionPolicy.RUNTIME)
61
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
62
@UnitsRelations(org.checkerframework.checker.units.qual.mol.class)
63
public @interface Substance {}
64
65
/**
66
* Luminous intensity (base unit: candela)
67
*/
68
@Documented
69
@Retention(RetentionPolicy.RUNTIME)
70
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
71
@UnitsRelations(org.checkerframework.checker.units.qual.cd.class)
72
public @interface Luminance {}
73
```
74
75
**Usage Examples:**
76
77
```java
78
import org.checkerframework.checker.units.qual.*;
79
80
public class BaseUnitsExample {
81
// Method that requires length measurements
82
public @Area double calculateArea(@Length double width, @Length double height) {
83
return width * height; // Length × Length = Area
84
}
85
86
// Method that requires mass and acceleration
87
public @Force double calculateForce(@Mass double mass, @Acceleration double acceleration) {
88
return mass * acceleration; // Mass × Acceleration = Force
89
}
90
91
// Method that requires time measurements
92
public @Speed double calculateSpeed(@Length double distance, @Time double time) {
93
return distance / time; // Length ÷ Time = Speed
94
}
95
96
public void example() {
97
@Length double width = 5.0; // 5 meters
98
@Length double height = 3.0; // 3 meters
99
@Mass double mass = 10.0; // 10 kilograms
100
@Time double time = 2.0; // 2 seconds
101
102
@Area double area = calculateArea(width, height); // 15 m²
103
@Speed double speed = calculateSpeed(width, time); // 2.5 m/s
104
@Acceleration double accel = 9.8; // 9.8 m/s²
105
@Force double force = calculateForce(mass, accel); // 98 N
106
}
107
}
108
```
109
110
### Derived Physical Units
111
112
Annotations for derived units computed from base units.
113
114
```java { .api }
115
/**
116
* Area measurement (Length²)
117
*/
118
@Documented
119
@Retention(RetentionPolicy.RUNTIME)
120
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
121
public @interface Area {}
122
123
/**
124
* Volume measurement (Length³)
125
*/
126
@Documented
127
@Retention(RetentionPolicy.RUNTIME)
128
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
129
public @interface Volume {}
130
131
/**
132
* Speed measurement (Length/Time)
133
*/
134
@Documented
135
@Retention(RetentionPolicy.RUNTIME)
136
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
137
public @interface Speed {}
138
139
/**
140
* Acceleration measurement (Length/Time²)
141
*/
142
@Documented
143
@Retention(RetentionPolicy.RUNTIME)
144
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
145
public @interface Acceleration {}
146
147
/**
148
* Force measurement (Mass × Length/Time²)
149
*/
150
@Documented
151
@Retention(RetentionPolicy.RUNTIME)
152
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
153
public @interface Force {}
154
155
/**
156
* Angular measurement
157
*/
158
@Documented
159
@Retention(RetentionPolicy.RUNTIME)
160
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
161
public @interface Angle {}
162
```
163
164
**Usage Examples:**
165
166
```java
167
import org.checkerframework.checker.units.qual.*;
168
169
public class DerivedUnitsExample {
170
// Physics calculations with proper unit checking
171
public @Volume double calculateVolume(@Length double length, @Length double width, @Length double height) {
172
return length * width * height; // Length³ = Volume
173
}
174
175
public @Acceleration double calculateAcceleration(@Speed double initialVelocity,
176
@Speed double finalVelocity,
177
@Time double time) {
178
return (finalVelocity - initialVelocity) / time; // (Speed - Speed) / Time = Acceleration
179
}
180
181
// Circular motion calculations
182
public @Speed double calculateCircularSpeed(@Length double radius, @Angle double angularVelocity, @Time double time) {
183
return radius * (angularVelocity / time); // Length × (Angle/Time) = Speed
184
}
185
186
public void physicsExample() {
187
// Geometric calculations
188
@Length double length = 10.0; // meters
189
@Length double width = 5.0; // meters
190
@Length double height = 2.0; // meters
191
@Volume double volume = calculateVolume(length, width, height); // 100 m³
192
193
// Motion calculations
194
@Speed double initialSpeed = 0.0; // m/s
195
@Speed double finalSpeed = 20.0; // m/s
196
@Time double accelerationTime = 4.0; // seconds
197
@Acceleration double acceleration = calculateAcceleration(initialSpeed, finalSpeed, accelerationTime); // 5 m/s²
198
199
// Force calculation
200
@Mass double mass = 5.0; // kg
201
@Force double force = mass * acceleration; // 25 N
202
}
203
}
204
```
205
206
### Specific Unit Annotations
207
208
Annotations for specific unit values and prefixes.
209
210
```java { .api }
211
/**
212
* Meters (base length unit)
213
*/
214
@Documented
215
@Retention(RetentionPolicy.RUNTIME)
216
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
217
@UnitsMultiple(quantity = Length.class, prefix = Prefix.one)
218
public @interface m {}
219
220
/**
221
* Kilometers (1000 meters)
222
*/
223
@Documented
224
@Retention(RetentionPolicy.RUNTIME)
225
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
226
@UnitsMultiple(quantity = Length.class, prefix = Prefix.kilo)
227
public @interface km {}
228
229
/**
230
* Square kilometers
231
*/
232
@Documented
233
@Retention(RetentionPolicy.RUNTIME)
234
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
235
@UnitsMultiple(quantity = Area.class, prefix = Prefix.kilo)
236
public @interface km2 {}
237
238
/**
239
* Cubic kilometers
240
*/
241
@Documented
242
@Retention(RetentionPolicy.RUNTIME)
243
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
244
@UnitsMultiple(quantity = Volume.class, prefix = Prefix.kilo)
245
public @interface km3 {}
246
247
/**
248
* Kilograms (base mass unit)
249
*/
250
@Documented
251
@Retention(RetentionPolicy.RUNTIME)
252
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
253
@UnitsMultiple(quantity = Mass.class, prefix = Prefix.one)
254
public @interface kg {}
255
256
/**
257
* Grams (0.001 kg)
258
*/
259
@Documented
260
@Retention(RetentionPolicy.RUNTIME)
261
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
262
@UnitsMultiple(quantity = Mass.class, prefix = Prefix.milli)
263
public @interface g {}
264
265
/**
266
* Seconds (base time unit)
267
*/
268
@Documented
269
@Retention(RetentionPolicy.RUNTIME)
270
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
271
@UnitsMultiple(quantity = Time.class, prefix = Prefix.one)
272
public @interface s {}
273
274
/**
275
* Hours (3600 seconds)
276
*/
277
@Documented
278
@Retention(RetentionPolicy.RUNTIME)
279
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
280
@UnitsMultiple(quantity = Time.class, prefix = Prefix.one)
281
public @interface h {}
282
283
/**
284
* Minutes (60 seconds)
285
*/
286
@Documented
287
@Retention(RetentionPolicy.RUNTIME)
288
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
289
@UnitsMultiple(quantity = Time.class, prefix = Prefix.one)
290
public @interface min {}
291
292
/**
293
* Kilometers per hour
294
*/
295
@Documented
296
@Retention(RetentionPolicy.RUNTIME)
297
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
298
public @interface kmPERh {}
299
300
/**
301
* Meters per second
302
*/
303
@Documented
304
@Retention(RetentionPolicy.RUNTIME)
305
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
306
public @interface mPERs {}
307
308
/**
309
* Newtons (force unit)
310
*/
311
@Documented
312
@Retention(RetentionPolicy.RUNTIME)
313
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
314
@UnitsMultiple(quantity = Force.class, prefix = Prefix.one)
315
public @interface N {}
316
317
/**
318
* Kilonewtons
319
*/
320
@Documented
321
@Retention(RetentionPolicy.RUNTIME)
322
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
323
@UnitsMultiple(quantity = Force.class, prefix = Prefix.kilo)
324
public @interface kN {}
325
```
326
327
**Usage Examples:**
328
329
```java
330
import org.checkerframework.checker.units.qual.*;
331
332
public class SpecificUnitsExample {
333
// Method that converts between different length units
334
public @m double convertToMeters(@km double kilometers) {
335
return kilometers * 1000.0; // km to m conversion
336
}
337
338
public @kg double convertToKilograms(@g double grams) {
339
return grams / 1000.0; // g to kg conversion
340
}
341
342
// Speed conversion
343
public @mPERs double convertSpeed(@kmPERh double kmPerHour) {
344
return kmPerHour / 3.6; // km/h to m/s conversion
345
}
346
347
public void conversionExample() {
348
// Distance measurements
349
@km double distanceKm = 5.0; // 5 kilometers
350
@m double distanceM = convertToMeters(distanceKm); // 5000 meters
351
352
// Mass measurements
353
@g double massGrams = 2500.0; // 2500 grams
354
@kg double massKg = convertToKilograms(massGrams); // 2.5 kilograms
355
356
// Time measurements
357
@h double timeHours = 2.0; // 2 hours
358
@min double timeMinutes = timeHours * 60; // 120 minutes
359
@s double timeSeconds = timeMinutes * 60; // 7200 seconds
360
361
// Speed measurements
362
@kmPERh double speedKmh = 72.0; // 72 km/h
363
@mPERs double speedMs = convertSpeed(speedKmh); // 20 m/s
364
365
// Force measurements
366
@N double forceNewtons = 100.0; // 100 Newtons
367
@kN double forceKiloNewtons = forceNewtons / 1000.0; // 0.1 kN
368
}
369
}
370
```
371
372
### Unit System Framework
373
374
Meta-annotations for defining unit relationships and prefixes.
375
376
```java { .api }
377
/**
378
* Defines relationships between units
379
*/
380
@Documented
381
@Retention(RetentionPolicy.RUNTIME)
382
@Target(ElementType.ANNOTATION_TYPE)
383
public @interface UnitsRelations {
384
Class<? extends Annotation>[] value();
385
}
386
387
/**
388
* Defines unit multiples and prefixes
389
*/
390
@Documented
391
@Retention(RetentionPolicy.RUNTIME)
392
@Target(ElementType.ANNOTATION_TYPE)
393
public @interface UnitsMultiple {
394
Class<? extends Annotation> quantity();
395
Prefix prefix();
396
}
397
398
/**
399
* SI prefixes for unit scaling
400
*/
401
public enum Prefix {
402
yocto, zepto, atto, femto, pico, nano, micro, milli, centi, deci,
403
one,
404
deca, hecto, kilo, mega, giga, tera, peta, exa, zetta, yotta
405
}
406
407
/**
408
* Indicates unknown units
409
*/
410
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
411
@DefaultQualifierInHierarchy
412
public @interface UnknownUnits {}
413
414
/**
415
* Bottom type for units hierarchy
416
*/
417
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
418
@SubtypeOf({Length.class, Mass.class, Time.class, Current.class, Temperature.class, Substance.class, Luminance.class})
419
public @interface UnitsBottom {}
420
421
/**
422
* Mixed or incompatible units
423
*/
424
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
425
@SubtypeOf(UnknownUnits.class)
426
public @interface MixedUnits {}
427
428
/**
429
* Polymorphic unit qualifier
430
*/
431
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
432
@PolymorphicQualifier(UnknownUnits.class)
433
public @interface PolyUnit {}
434
```
435
436
**Usage Examples:**
437
438
```java
439
import org.checkerframework.checker.units.qual.*;
440
441
// Define a custom unit with relationships
442
@UnitsRelations({m.class, km.class})
443
@Target({ElementType.TYPE_USE})
444
@Retention(RetentionPolicy.RUNTIME)
445
public @interface Distance {}
446
447
// Define a custom prefixed unit
448
@UnitsMultiple(quantity = Length.class, prefix = Prefix.milli)
449
@Target({ElementType.TYPE_USE})
450
@Retention(RetentionPolicy.RUNTIME)
451
public @interface mm {}
452
453
public class UnitFrameworkExample {
454
// Polymorphic method that preserves unit types
455
public @PolyUnit double scale(@PolyUnit double value, double factor) {
456
return value * factor;
457
}
458
459
// Method that handles mixed units safely
460
public double convertToBaseUnits(@MixedUnits double value, String unitType) {
461
switch (unitType) {
462
case "km": return value * 1000.0; // Convert km to m
463
case "cm": return value / 100.0; // Convert cm to m
464
case "mm": return value / 1000.0; // Convert mm to m
465
default: return value; // Assume base unit
466
}
467
}
468
469
public void frameworkExample() {
470
@m double meters = 100.0;
471
@km double kilometers = 2.0;
472
473
// Polymorphic scaling preserves units
474
@m double scaledMeters = scale(meters, 1.5); // 150 m
475
@km double scaledKm = scale(kilometers, 0.5); // 1 km
476
477
// Handle mixed units when necessary
478
@MixedUnits double mixedValue = 500.0;
479
double normalized = convertToBaseUnits(mixedValue, "cm"); // 5 m
480
}
481
}
482
```
483
484
### Angular Measurements
485
486
Annotations for angular quantities and rotational calculations.
487
488
```java { .api }
489
/**
490
* Angle in degrees
491
*/
492
@Documented
493
@Retention(RetentionPolicy.RUNTIME)
494
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
495
@UnitsMultiple(quantity = Angle.class, prefix = Prefix.one)
496
public @interface degrees {}
497
498
/**
499
* Angle in radians
500
*/
501
@Documented
502
@Retention(RetentionPolicy.RUNTIME)
503
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
504
@UnitsMultiple(quantity = Angle.class, prefix = Prefix.one)
505
public @interface radians {}
506
```
507
508
**Usage Examples:**
509
510
```java
511
import org.checkerframework.checker.units.qual.*;
512
513
public class AngularExample {
514
public @radians double degreesToRadians(@degrees double degrees) {
515
return degrees * Math.PI / 180.0;
516
}
517
518
public @degrees double radiansToDegrees(@radians double radians) {
519
return radians * 180.0 / Math.PI;
520
}
521
522
// Trigonometric functions with unit checking
523
public double sine(@radians double angle) {
524
return Math.sin(angle); // Math.sin expects radians
525
}
526
527
public @Length double calculateArcLength(@Length double radius, @radians double centralAngle) {
528
return radius * centralAngle; // s = r × θ (in radians)
529
}
530
531
public void trigonometryExample() {
532
@degrees double angleDeg = 45.0; // 45 degrees
533
@radians double angleRad = degreesToRadians(angleDeg); // π/4 radians
534
535
double sinValue = sine(angleRad); // sin(π/4) = √2/2
536
537
@Length double radius = 10.0; // 10 meters
538
@Length double arcLength = calculateArcLength(radius, angleRad); // ~7.85 meters
539
540
@degrees double backToDegrees = radiansToDegrees(angleRad); // 45 degrees
541
}
542
}
543
```