什么时候在java中使用Long vs long?
以下是我的界面 –
public interface IDBClient { public String read(ClientInput input); }
这是我实现的界面 –
public class DatabaseClient implements IDBClient { @Override public String read(ClientInput input) { } }
现在我有一个像这样获取DatabaseClient
实例的工厂 –
IDBClient client = DatabaseClientFactory.getInstance(); ....
现在我需要调用我的DatabaseClient
read
方法,该方法接受ClientInput
参数,下面是相同的类。 这堂课不是我写的,所以这就是我对此有疑问的原因,我非常确定这是错误的做法。
public final class ClientInput { private Long userid; private Long clientid; private Long timeout_ms = 20L; private boolean debug; private Map parameterMap; public ClientInput(Long userid, Long clientid, Map parameterMap, Long timeout_ms, boolean debug) { this.userid = userid; this.clientid = clientid; this.parameterMap = parameterMap; this.timeout_ms = timeout_ms; this.debug = debug; } }
因此,当客户调用DatabaseClient
read
方法时,他们将像这样创建ClientInput
参数,然后使用工厂获取DatabaseClient
的实例,然后相应地调用read方法。
Map paramMap = new HashMap(); paramMap.put("attribute", "segmentation"); ClientInput input = new ClientInput(109739281L, 20L, paramMap, 1000L, true); IDBClient client = DatabaseClientFactory.getInstance(); client.read(input);
问题陈述:-
- 所以我的第一个问题是
userid
,clientid
,timeout_ms
应该是Long
对象还是只是在ClientInput
类中long
? - 我的第二个问题是,客户可能会传递错误信息,例如
negative user ids
,negative client id
,negative timeout
值等等。那么我应该在哪里进行此validation? 我应该在ClientInput
类的构造函数中还是在其他位置执行此validation检查? 这样做的更好方法是什么?如何进行validation?
我认为没有一个正确的答案。 一些建议:
-
在这种情况下,我在long和Long之间看到的最大区别是Long可能为null。 如果有可能您可能缺少值,则Long对象将有用,因为null可以指示缺失值。 如果你正在使用原语,你将不得不使用一些特殊的值来表示缺失,这可能会是一团糟。 速度或大小不太可能是一个问题,除非你计划制作一百万个这样的东西,然后序列化。
-
我对validation逻辑的偏好是在事物可能失败的时候抛出某种自定义的ValidationException。 如果你只是用构造函数创建这些东西,最简单的方法就是在那里validation,例如
public ClientInput(Long userid, Long clientid, Map
parameterMap, Long timeout_ms, boolean debug) throws ValidationException { if (userid == null) throw new ValidationException("UserId is required"); ...etc, etc... } 最终,validationException仅在您可以使用它执行某些操作的时候捕获它时才有用 – 将其回显给用户或其他任何东西。
long
是原始的, 必须有一个值。 简单。
Long
是一个对象 ,所以:
- 它可以为
null
(意思是你喜欢什么,但“未知”是一种常见的解释) - 它可以传递给一个接受
Object
,Number
,Long
或long
参数的方法(最后一个由于自动拆箱) - 它可以用作通用参数类型,即
List
是OK,但List
不行 - 它可以通过java序列化机制进行序列化/反序列化
总是使用最简单的东西,所以如果你需要Long
任何function,请使用Long
否则使用long
。 Long
的开销非常小,但它确实存在。
1 Long是面向对象的长对立部分。 区别如下,它适用于Float浮动,整数转换为整数等。
- long是一个原始类型,而Long是一个Java类(因此它将inheritanceObject)。
- long必须分配有效数字,而Long可以为null
- long实例不能使用OO的好处,而Long的实例是真正的Java对象
- Long是可序列化的,因此在执行文件,数据库或网络IO时非常有用
- 考虑到内存空间和处理速度,long比Long更有效
如果您正在进行繁重的计算,请使用原始类型。 否则,如果您更关注设计,对象计数器部件将非常有用。
2由于如果我正确观察你没有使用任何框架,我建议你使用方法bool validate()创建一个类似Validated的接口。 每当您尝试将输入放入数据库时,请提前进行validation。
1)如果需要将值视为对象,请使用Long。 否则长时间使用; 它效率更高。
2)判断电话,真的。 更深入的意味着即使值来自您信任的来源,您也会检查,但这可能会在其他代码中发现错误。 更接近用户输入意味着您失去了深度理智检查(并且可能需要在多个地方办理登机手续),但避免花时间检查您已检查的内容。 什么是最好的取决于您计划将来如何使用/增强此代码。
-
因为
Long
是包装类的privimitive类型long
而Long
是一个类,它表示它的实例可以为null。 在我看来,使用包装类比原始类型更好,因为它可能null
状态,这可以告诉我们更多的信息。
另外,包装类会自动初始化为0,对于懒惰使用很有用。 -
对于数据validation,我认为你最好在
controller
而不是DAO
,然后有一个很好的方法来处理它或提醒用户修改它们!
Long类的优点是值可以为null。 在您的情况下,如果没有提供Long ID,如果您使用类似的东西快速检测到它。
public ClientInput(Long userid, Long clientid, Map parameterMap, Long timeout_ms, boolean debug) { if (userid == null) { throw new IllegalArgumentException("userid is null"); }
对于第二个问题,您也可以将IDvalidation放在构造函数中。 这可确保如果ID为null或无效,则永远不会创建ClientInput。 但是对于你进行此validation的位置没有“最佳”答案,这取决于你的其余代码的结构,但理想情况下你想尽早捕获这些东西。
public ClientInput(Long userid, Long clientid, Map parameterMap, Long timeout_ms, boolean debug) { if (userid == null || userid < USER_ID_MIN || userid > USER_ID_MAX ) { throw new IllegalArgumentException("userid is invalid"); }
另一种选择是将userid参数作为Long接受,测试它为null,但是一旦你知道它有效,就将它存储为私有的,原始的long。
我尝试保持Bean对象尽可能简单,这意味着在其他地方处理validation – 在单独的Validator类或validate()方法中。 一般算法是一样的:
- validateInputParametres()
- readDb()
我会做的事情如下:
final ClientInput input = new ClientInput(109739281L, 20L, paramMap, 1000L, true); validate(input); // throw/handle exceptions here final Map paramMap = new HashMap(); paramMap.put("attribute", "segmentation"); final IDBClient client = DatabaseClientFactory.getInstance(); client.read(input);