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).
2
It won’t work with double
or float
because as you noticed you can’t create a generic for primitive types. But it will work with the boxed types Double
and 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 Number
with 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.
3
@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 Double
or 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 double
.
The space overhead goes down if you store all the values in a double[]
or 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 FloatVector
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 double
(or float
) values.