【问题标题】:Why cast a String to a String?为什么要将字符串转换为字符串?
【发布时间】:2016-03-11 23:42:30
【问题描述】:

Oracle Java 社区网站上的一篇文章作为示例(对于 JPA 转换器,但我猜这无关紧要)提供了以下方法:

public Boolean convertToEntityAttribute(String y) {
    String val = (String) y;
    if(val.equals("Y")){
        return true;
    } else {
        return false;
    }
}

将字符串 y 转换为字符串 val 有什么用?这样做有正当理由吗?

原文:What's New in JPA

【问题讨论】:

  • return val.equals("Y") 就足够了...
  • 不需要这种多余的转换。
  • 开发者的错误,就像你我一样。感谢您的识别:)
  • Tunaki - 我会写回 "Y".equals(val)
  • 整个示例代码很糟糕。首先,AttributeConverter 需要两个类型参数(正如您所料,它们是您转换自/转换为的两种类型),作者忽略了这一点。结果,该示例甚至无法编译。然后是不必要的演员表,锦上添花的是if (boolean) {return true;} else {return false;} 构造。

标签: java string


【解决方案1】:

这样的演员阵容是完全没有必要的。我可以想象它是以前的

public Boolean convertToEntityAttribute(Object y) {
    String val = (String) y;
    ...
}

但后来参数类型更改为String,作者只是忘记删除演员表。

【讨论】:

    【解决方案2】:

    这种多余的强制转换是没有用的。

    当前代码可以简化为

    public Boolean convertToEntityAttribute(String y) {
        return "Y".equals(y);
    }
    

    【讨论】:

    • 请注意,这是另一回事 - 文章中的代码会在空值上抛出 NPE,而这不会。在某些情况下,需要对空值进行 NPE。
    • @eis 这两种情况都不会导致 NPE,您可以将 null 转换为任何引用类型而不会出现任何异常stackoverflow.com/questions/18723596/…
    • @Ian2thedv 但是你当然不能在没有异常的情况下调用 val.equals() 空值
    • @eis 你不会得到NPE。你指的是什么?
    • @RuchiraGayanRanaweera 你会在原始代码中,所以这不等同于那个。
    【解决方案3】:

    这样做有正当理由吗?

    什么都没有1

    但另一方面是 Java 编译器知道类型转换是不必要的,并将其优化掉。所以唯一的“损害”是可读性。

    例如。

    [stephen@blackbox tmp]$ cat Test.java 
    public class Test {
        public void test (String x) {
            String s = (String) x;
            System.out.println(s);
        }
    }
    [stephen@blackbox tmp]$ javac Test.java 
    [stephen@blackbox tmp]$ javap -c Test
    Compiled from "Test.java"
    public class Test {
      public Test();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public void test(java.lang.String);
        Code:
           0: aload_1
           1: astore_2
           2: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
           5: aload_2
           6: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
           9: return
    }
    [stephen@blackbox tmp]$ 
    

    语句String s = (String) x;被编译为简单的加载和存储;没有checkcast 指令。

    如果 JIT 编译器能够优化掉多余的 checkcast ...,我不会感到惊讶。


    1 - ...手写代码。在生成的源代码中,冗余类型转换可用于简化源代码生成器的编写。毕竟,生成代码的可读性在很大程度上是无关紧要的。

    【讨论】:

      猜你喜欢
      • 2015-09-04
      • 2019-10-10
      • 2019-01-05
      • 1970-01-01
      • 1970-01-01
      • 2017-11-29
      • 2011-08-22
      • 2014-01-29
      • 1970-01-01
      相关资源
      最近更新 更多