views:

108

answers:

4

I am designing an API. It will have a lot of methods which do the same, but have a different parameter primitives.

public void someMethod1(int x);
public void someMethod1(float x);
public void someMethod1(double x);
public void someMethod2(int x, int y);
...
public void someMethod3(int x, int y, int z);
...

Due to the primitives, I have to copy & paste a lot, which I think is quite unmaintainable over time. Is it a good idea to avoid primitives in methods and constructors? For instance, the replacement of the above will be:

public <T extends Number> void someMethod1(T x);
public <T extends Number> void someMethod2(T x, T y);
public <T extends Number> void someMethod3(T x, T y, T z);

Edit:

What are the downsides of this?

+4  A: 

It will be usable, because of autoboxing / autounboxing in Java 1.5 and later. You can pass an int to something that expects an Integer, or vice versa, and the cast will happen automatically. The same applies to return values.

Keep in mind that in the body of your method, you will know little more about your arguments than that they are some form of Number. This will only be suitable if you don't care to differentiate between integer and floating-point representations.

It will not increase your performance - there will be some small penalty for the cast, but you shouldn't worry about that until you discover you have a bottleneck. For most applications, the difference will be insignificant.

Whether you use a List rather than an array should really be decided by your design, but it is generally advisable to use a List unless an array is necessarily needed. Lists tend to be more flexible, don't need to be resized, have all of the benefits of the Collections API, etc.

danben
+1  A: 

APIs are about semantics, so I think the answer to the question as stated (Should I avoid primitives in API design) is that it depends on what your API does.

int addOne(int integer) is semantically consistent and won't present many problems with maintenance as it reflects the problem domain.

Employee getEmployee(int empID) could be classed as inappropriate and will present maintenance issues if your employee IDs change, say, to Strings.

Brabster
+2  A: 

To answer your question about List<T> vs. T[], both expose details about implementation.

List<T> is more maintainable than T[] because you can change the List implementation without changing client code.

If the list shouldn't be modified by the client code, Iterable<T> would be better, as you expose nothing about your implementation details and prevent operations other than iteration.

Brabster
Iterable is a nice one! Thank you!
Pindatjuh
P.S. I edited the question: this is an answer for the question wether `List<T>` was a good replacement for `T[]`.
Pindatjuh
+1  A: 

It's a valid pattern, sometimes used for defining properties in a model-view-controller system. Additionally, if you use ints in the range of -128 to 127, they will be auto-cached by Java if you convert using Integer.valueOf(int) which can speed things up a bit regarding Integer creation. You can also increase the cached range using the property java.lang.Integer.IntegerCache.high which is always at least 127. It might be the case also that auto-boxing will also use this Integer cache, but I'm unsure. If your class is designed for use in a high-performance environment, I'd consider other alternatives instead and use primitives.

Chris Dennett