I’m trying to create a vector (like in physics) class in Java.
I want to support vector addition, dot product, scalar multiplication, etc.
So, my question is, is it possible to do this with generics? Generics can only take objects as parameters but I’d like to use primitives (double or float).
It won’t work with
float because as you noticed you can’t create a generic for primitive types. But it will work with the boxed types
Float. Due to autoboxing this won’t make much of a difference in practice.
That means you can create a generic which can be used with anything that extends
public class PhysicsVector<T extends Number>.
Unfortunately you can’t do arithmetics on
Number. That means all your methods will have to convert the values to their floating point representation by calling
.doubleValue() on them.
@Philipp’s answer is right on for your direct question but let’s step back to revisit assumptions.
First assumption: You’re using Java 8 or earlier. (A future version will support Generics over Primitive Types.)
Second, why use generics here? Potentially to save space if you have a very large number of vectors in memory, but boxing will take more space per vector than saved by using
float instead of
double. A 3D vector object holding 3
Float values will require 4 heap nodes and consequent indirection and CPU cache misses.
Generics will add complexity as well as space and time overhead. Generified code will do all the math with
double values so it won’t save CPU math time, in fact it’ll cost extra math time converting
float values to
The space overhead goes down if you store all the values in a
float since it’s a single box for all the values, but there’s still an extra heap node per instance, and now there are array bounds checks on every number fetch and store.
If you really want to save space with a very large number of vectors in memory, the way to do it in Java 8 is to have an abstract
Vector class with an API that uses
double values, and
DoubleVector subclasses that directly hold 3 primitive values.
Again, if you don’t have a lot of them in memory, just go for a simple
Vector class that holds