【问题标题】:How to prevent an Object being cast to a String automatically如何防止对象自动转换为字符串
【发布时间】:2011-05-25 17:28:07
【问题描述】:

我有一个如下所示的类:

public class FileEntry {
    private String name;
    public FileEntry (String name) {
        this.name = name;
    }
}

void foo(String arg){};
foo("string" + new FileEntry("")); // How to get a compile error here

如何让 java 给我一个编译错误,而不是自动将 Object 转换为 String?

【问题讨论】:

  • “我在一个带有字符串参数的方法上使用这个类” - 等等,wat?那么意思是,当您传递方法调用的结果时?该方法的返回类型是什么?
  • 向我们展示您正在使用它的示例代码,它会引发异常。
  • 听起来您需要重新考虑一下您的设计。什么情况下需要这个?
  • 我不相信我认为我理解的东西。你能展示发生“转换为字符串”的实际代码吗?
  • @delnan - 是的,我不明白这一点。肯定将 FileEntry 传递给采用 String 的方法会导致编译错误?

标签: java compiler-errors type-conversion java-6


【解决方案1】:

如果你有

void foo(String bar)
{

}

然后你打电话

foo(new FileEntry());

会有一个编译器错误。见here

只有当你执行类似的操作时才会调用 toString()

foo("this is foo" + new FileEntry());

【讨论】:

  • 感谢您的所有回答。你说的对。该问题在字符串转换中引起。但是,如果有一种方法可以检测到这个编译时间,那就太好了。将编辑我的问题
【解决方案2】:

在编译时是不可能做到的。在运行时,您可以从覆盖的 toString 方法中抛出异常

【讨论】:

    【解决方案3】:

    调用toString()与强制转换相同 - 您需要注意区别。

    您可以覆盖toString() 不仅会引发异常,而且会被弃用:

    @Deprecated @Override
    public String toString() {
        throw new IllegalStateException("toString mustn't be called on this class");
    }
    

    如果表达式的编译时类型是FileEntry,那在编译时有帮助。在大多数配置下,它也只是一个警告。

    这也可能会混淆尝试自动调用toString() 等的调试器。

    【讨论】:

      【解决方案4】:

      除了覆盖toString() 并在里面抛出异常之外,我想不出任何其他方法。

      【讨论】:

        【解决方案5】:

        如果我在一个方法上使用这个类 Java 编译器将使用的字符串参数 自动将其转换为字符串 对象使用 toString()

        不,不会。它将调用一个带有Object 参数的重载方法,如果存在这样的方法 - 并且此类方法通常会在参数上调用toString()

        您无法阻止使用重载方法 - 毕竟它们是故意放在那里的。

        【讨论】:

          【解决方案6】:

          正如其他人指出的那样,"str" + obj 不涉及类型转换。

          它既不涉及重载,也不涉及对String.concat(String)的调用。 (事实上​​,当str2null 时,str1.concat(str2) 给出的结果与str1 + str2 不同!)

          从技术上讲,这称为“字符串转换”;见JLS 5.1.11。转换等效于调用String.valueOf(Object) 或调用相关原始包装类的静态toString(primitive) 方法。

          【讨论】:

            【解决方案7】:

            正如 cmets 中所述,我不明白到底发生了什么。但是 FileEntry@6e470ce1 很可能是 FileEntry 的 toString 方法的结果。你可以覆盖它以返回任何你想要的,只要它是一个字符串。

            【讨论】:

              【解决方案8】:

              我不确定你为什么不直接在FileEntry 中实现toString() 方法。如果你真的想要一个编译错误,你可以创建一个基本抽象类,如:

              public abstract class ForceImplementToString {
                @Override
                public abstract String toString();
              }
              

              然后像这样创建你的类,它会产生一个编译错误,你必须实现toString() 方法:

              public class FileEntry extends ForceImplementToString {
                  private String name;
                  public FileEntry (String name) {
                      this.name = name;
                  }
              }
              

              【讨论】:

                【解决方案9】:

                Object 类有一个 toString(),它被 Java 中的每个类继承(因为每个类都派生自 Object)。这个toString() 将被调用(除非它被覆盖,在这种情况下,特定对象的覆盖toString() 将被调用)。

                您无法采取任何措施来防止这种情况发生。

                另一方面,您的方法是什么样的?如果你有public myMethod(String arg) 并调用myMethod(new FileEntry()),我很确定这会导致编译时错误。

                当然,如果您有一个以Object arg 作为参数的重载方法,那么这就是将被调用的方法。在内部,这个方法可能是在arg 上调用toString()。此外,在字符串上下文中使用不是字符串的对象(例如,如果将其连接到字符串),会导致对该对象的 toString() 的隐式调用(可以是被覆盖的对象,也可以是默认值)来自Object)。

                要从toString() 获得更漂亮的结果,您应该在FileEntry 类中覆盖toString(),以便打印更有意义的内容。

                【讨论】:

                  【解决方案10】:

                  我不认为你的前提是正确的。 Java 不会自动将对象转换为字符串。这段代码:

                  public class Foo {
                      public static void main(String[] args) {
                          Foo foo = new Foo();
                          String got = "Concatenated: ".concat(foo);
                          System.out.println(got);
                      }
                      public String toString() {
                          return "Foo object";
                      }
                  }
                  

                  从我的 Java 1.6.0_23 编译器生成此输出:

                  Foo.java:4: concat(java.lang.String) in java.lang.String cannot be applied to (Foo)  
                              String got = "Concatenated: ".concat(foo);
                                                           ^
                  1 error
                  

                  【讨论】:

                    【解决方案11】:

                    您总是可以下载 java 的源代码,然后从 Object 中删除 toString()。

                    【讨论】:

                    • 那就不再是java了
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-03-30
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-04-07
                    • 2021-07-02
                    相关资源
                    最近更新 更多