1

我有一个如下所示的类:

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?

4

11 回答 11

9

如果你有

void foo(String bar)
{

}

你打电话给

foo(new FileEntry());

会有编译器错误。看这里

仅当您执行类似的操作时才会调用 toString()

foo("this is foo" + new FileEntry());
于 2011-05-25T17:32:17.977 回答
6

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

于 2011-05-25T17:30:47.957 回答
4

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

您可以覆盖toString()以不仅抛出异常,而且不推荐使用:

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

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

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

于 2011-05-25T17:37:01.097 回答
2

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

于 2011-05-25T17:30:34.283 回答
1

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

它既不涉及重载,也不涉及调用String.concat(String). (确实,与when isstr1.concat(str2)给出不同的结果!)str1 + str2str2null

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

于 2011-05-26T12:43:40.197 回答
1

如果我在带有 String 参数的方法上使用此类,Java 编译器将使用 toString() 自动将其转换为 String 对象

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

您无法采取任何措施来防止使用重载方法——毕竟它们是故意放在那里的。

于 2011-05-25T17:34:12.267 回答
0

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

于 2011-05-25T17:33:46.197 回答
0

我不确定你为什么不只是toString()FileEntry. 如果你真的想要一个编译错误,你可以创建一个基本的抽象类,如:

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;
    }
}
于 2011-05-25T17:35:49.550 回答
0

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

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

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

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

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

于 2011-05-25T17:37:33.193 回答
0

我不认为你的前提是正确的。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
于 2011-05-25T17:45:07.113 回答
-1

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

于 2011-07-26T23:18:47.980 回答