【问题标题】:When to use Long vs long in java?什么时候在java中使用Long vs long?
【发布时间】:2014-01-28 20:57:58
【问题描述】:

下面是我的界面 -

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<String, String> parameterMap;

    public ClientInput(Long userid, Long clientid, Map<String, String> 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的Instance,然后相应地调用read方法。

Map<String, String> paramMap = new HashMap<String, String>();
paramMap.put("attribute", "segmentation");

ClientInput input = new ClientInput(109739281L, 20L, paramMap, 1000L, true);

IDBClient client = DatabaseClientFactory.getInstance();
client.read(input);

问题陈述:-

  1. 所以我的第一个问题是userid、clientid、timeout_ms 应该是Long 对象还是只是long 类中的long?
  2. 我的第二个问题是,客户可能会传递错误信息,例如negative user ids、negative client id、negative timeout 值等。那么我应该在哪里进行此验证?我应该在 ClientInput 类的构造函数中还是在其他地方进行此验证检查?执行此操作的更好方法是什么?我应该如何进行验证?

【问题讨论】:

  • 您提出了两个截然不同的问题。您应该发布两个单独的帖子,因为 Stackoverflow 并不是一个讨论组。我很确定你会发现这两个问题都被问过很多次,也被回答过很多次。在第一个问题上,搜索何时使用对象以及何时使用原语。对于第二个问题,搜索参数/参数的验证。

标签: java map constructor


【解决方案1】:

long 是一个原语,必须有一个值。很简单。

Long 是一个对象,所以:

  • 它可以是null(意思是你喜欢的任何东西,但“未知”是一种常见的解释)
  • 可以将它传递给接受Object、Number、Long 或long 参数的方法(最后一个要归功于自动拆箱)
  • 它可以用作泛型参数类型,即List&lt;Long&gt; 可以,但List&lt;long&gt; 不是可以
  • 可以通过java序列化机制进行序列化/反序列化

始终使用最简单的方法,因此如果您需要Long 的任何功能,请使用Long,否则请使用long。 Long 的开销非常小,但确实存在。

【讨论】:

    【解决方案2】:

    我认为没有一个正确的答案。一些建议:

    • 在这种情况下,我看到long 和Long 之间的最大区别是Long 可能是null。如果您可能有缺失值,Long 对象将很有帮助,因为null 可以指示缺失值。如果您使用原语,则必须使用一些特殊值来指示缺失,这可能会很混乱。速度或大小不太可能成为问题,除非您计划制作一百万个这样的数组然后序列化。

    • 我对验证逻辑的偏好是在事情可能失败的地方抛出某种自定义ValidationException。如果您只是使用构造函数创建这些东西,最简单的方法就是在那里进行验证,例如

       public ClientInput(Long userid, Long clientid, Map<String, String> parameterMap, Long timeout_ms, boolean debug) throws ValidationException {          
      
            if (userid == null) throw new ValidationException("UserId is required"); 
                  ...etc, etc...
      }
      

    最终,ValidationException 仅在您可以在可以用它做一些有用的事情时抓住它时才有用 - 将其回显给用户或其他任何东西。

    【讨论】:

    • 我做同样的史蒂夫,只是我使用了 IllegalArgumentException。但是,是的,Long 是一个很长的包装器。使用 Long 的唯一真正优势是等同于引用而不是值,或者使用 null 作为一些特殊的标记。
    【解决方案3】:

    1 Long 是 long 的面向对象的对应部分。区别如下,适用于Float转float、Integer转整数等。

    • long 是原始类型,而 Long 是 Java 类(因此它将继承 Object)。
    • long 必须指定一个有效数字,而 Long 可以为 null
    • long 实例无法利用 OO 的优势,而 Long 实例是真正的 Java 对象
    • Lo​​ng 是可序列化的,因此在进行文件、数据库或网络 IO 时非常有用
    • 考虑到内存空间和处理速度,long 比 Long 更高效

    如果您要进行大量计算,请使用原始类型。否则,如果您更关心设计,对象计数器部件将非常有用。

    2 如果我观察正确,由于您没有使用任何框架,我建议您使用 bool validate() 方法制作一个类似 Validated 的接口。并且每次您尝试将输入放入数据库时​​,都会提前调用 validate。

    【讨论】:

      【解决方案4】:

      1) 如果您需要将值视为对象,请使用 Long。否则使用 long ;效率更高。

      2) 判决电话,真的。更深入地表示,即使值来自您信任的来源,您也要进行检查,但这可能会捕获其他代码中的错误。将其放在更靠近用户输入的位置意味着您将失去深入的完整性检查(并且可能需要在多个地方进行检查),但可以避免花时间检查您已经检查过的内容。什么是最好的取决于您计划在未来如何使用/增强此代码。

      【讨论】:

        【解决方案5】:
        1. 因为Long 是封装类私有类型long 而Long 是一个类,这表明它的实例可以为空。在我看来,使用包装类比原始类型更好,因为其中可能有 null 状态,这可以告诉我们更多信息。
          另外,wrapper 类会自动初始化为 0,适合懒惰使用。

        2. 对于数据验证,我认为你最好在controller而不是DAO,然后有一个好的方法来处理这个或者提醒用户修改它们!

        【讨论】:

          【解决方案6】:

          Long 类的优点是值可以为空。在你的情况下,如果没有提供 Long ID,如果你用类似的东西快速检测到这个。

          public ClientInput(Long userid, Long clientid, Map<String, String> parameterMap, Long timeout_ms, boolean debug) {
              if (userid == null) {
                    throw new IllegalArgumentException("userid is null");
              }
          

          对于第二个问题,您也可以将 ID 验证放在构造函数中。这确保了如果 ID 为 null 或无效,则永远无法创建 ClientInput。但是对于您将验证放在哪里没有“最佳”答案,这取决于其余代码的结构,但理想情况下您希望尽早捕获这些内容。

          public ClientInput(Long userid, Long clientid, Map<String, String> 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,一旦你知道它是有效的。

          【讨论】:

            【解决方案7】:

            我尝试使 Bean 对象尽可能简单,这意味着在其他地方处理验证 - 在单独的 Validator 类中或在 validate() 方法中。通用算法是一样的:

            • 验证输入参数()
            • readDb()

            我会这样做:

            final ClientInput input = new ClientInput(109739281L, 20L, paramMap, 1000L, true);
            validate(input); // throw/handle exceptions here
            
            final Map<String, String> paramMap = new HashMap<String, String>();
            paramMap.put("attribute", "segmentation");
            
            final IDBClient client = DatabaseClientFactory.getInstance();
            client.read(input);
            

            【讨论】:

              猜你喜欢
              • 2011-08-17
              • 2016-07-29
              • 2012-01-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-01-07
              • 1970-01-01
              相关资源
              最近更新 更多