在 API 设计中避免使用原语?
我正在设计一个API。它将有很多执行相同操作但具有不同参数原语的方法。
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);
...
由于原语,我必须复制并复制它。粘贴了很多,我认为随着时间的推移这是相当难以维护的。在方法和构造函数中避免使用原语是个好主意吗?例如,上面的替换将是:
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);
编辑:
这有什么缺点?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
由于 Java 1.5 及更高版本中的自动装箱/自动拆箱功能,它将可用。您可以将
int
传递给需要Integer
的对象,反之亦然,并且转换将自动发生。这同样适用于返回值。请记住,在方法的主体中,您对参数的了解只不过是它们是某种形式的
Number
。仅当您不关心区分整数和浮点表示形式时,这才适用。它不会提高你的表现——演员阵容将会受到一些小惩罚,但在你发现你有瓶颈之前你不应该担心这一点。对于大多数应用程序来说,差异是微不足道的。
是否使用
List
而不是数组实际上应该由您的设计决定,但通常建议使用List
,除非必须需要数组。List
往往更灵活,不需要调整大小,具有Collections
API 的所有优点等。It will be usable, because of autoboxing / autounboxing in Java 1.5 and later. You can pass an
int
to something that expects anInteger
, 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 aList
unless an array is necessarily needed.List
s tend to be more flexible, don't need to be resized, have all of the benefits of theCollections
API, etc.要回答有关
List
与T[]
的问题,两者都会公开有关实现的详细信息。List
比T[]
更易于维护,因为您可以更改 List 实现而无需更改客户端代码。如果客户端代码不应修改列表,则
Iterable
会更好,因为您不会公开任何有关实现细节的内容,并且会阻止迭代以外的操作。To answer your question about
List<T>
vs.T[]
, both expose details about implementation.List<T>
is more maintainable thanT[]
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.API 与语义有关,因此我认为上述问题(我是否应该在 API 设计中避免使用原语)的答案是,它取决于您的 API 的用途。
int addOne(int integer)
在语义上是一致的,并且不会出现很多维护问题,因为它反映了问题域。Employee getEmployee(int empID)
可能会被归类为不适当的,并且如果您的员工 ID 更改(例如更改为字符串),则会出现维护问题。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.这是一种有效的模式,有时用于定义模型-视图-控制器系统中的属性。此外,如果您使用 -128 到 127 范围内的整数,并且使用
Integer.valueOf(int)
这可以加快一点整数
创建。您还可以使用属性java.lang.Integer.IntegerCache.high 增加缓存范围
始终至少为 127。自动装箱也可能会使用此整数缓存,但我不确定。如果您的类设计用于高性能环境,我会考虑其他替代方案并使用原语。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 regardingInteger
creation. You can also increase the cached range using the propertyjava.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.