如何防止对象自动转换为字符串

发布于 2024-11-10 00:13:10 字数 313 浏览 3 评论 0原文

我有一个如下所示的类:

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

How can I make java 给我一个编译错误而不是自动将对象转换为字符串?

I have a class that looks like the following:

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

How can I make java give me a compile error instead of automatically converting the Object to a String?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

掀纱窥君容 2024-11-17 00:13:10

如果你有

void foo(String bar)
{

}

并且你调用

foo(new FileEntry());

将会出现编译器错误。请参阅此处

仅当您执行以下操作时才会调用 toString()

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

If you have

void foo(String bar)
{

}

and you call

foo(new FileEntry());

there will be a compiler error. See here

The the toString() will be called only if you do something like

foo("this is foo" + new FileEntry());
手心的海 2024-11-17 00:13:10

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

it is impossible to do it in the compile time. in the runtime you can throw an exception from the overridden toString method

合久必婚 2024-11-17 00:13:10

调用 toString() 与转换不同 - 您需要了解其中的差异。

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

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

如果表达式的编译时类型为 ,这将在编译时有所帮助。代码>文件条目。在大多数配置下,它也只是一个警告。

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

Calling toString() is not the same as casting - you need to be aware of the difference.

You could override toString() to not only throw an exception, but be deprecated:

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

That will only help at compile-time if the compile-time type of the expression is FileEntry. It will also just be a warning under most configurations.

This will also potentially confuse debuggers which try to call toString() automatically, etc.

時窥 2024-11-17 00:13:10

除了重写 toString() 并在内部抛出异常之外,我想不出任何其他方法。

I can't think of any other way than to override toString() and throw an Exception inside.

ζ澈沫 2024-11-17 00:13:10

如果我在带有
java编译器将字符串参数
自动将其转换为字符串
使用 toString() 的对象

不,不会。它将执行的操作是调用一个采用 Object 参数的重载方法(如果存在这样的方法),并且此类方法通常会对参数调用 toString()

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

If I use this class on a method with a
String argument the java compiler will
automatically convert this to a String
object using toString()

No, it won't. What it will do is call an overloaded method that takes an Object parameter, if such a method exists - and such methods often call toString() on the parameter.

There's nothing you can do to prevent overloaded methods from being used - they were put there on purpose, after all.

作死小能手 2024-11-17 00:13:10

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

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

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

As others have pointed out, "str" + obj does not involve a type cast.

It does not involve overloading either, or a call to String.concat(String). (Indeed, str1.concat(str2) gives a different result to str1 + str2 when str2 is null!)

Technically speaking, this is called a "string conversion"; see JLS 5.1.11. The conversion is equivalent to a call to String.valueOf(Object) or a call to the static toString(primitive) method of the relevant primitive wrapper class.

雨后彩虹 2024-11-17 00:13:10

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

As mentioned in the comments, I don't understand what exactly is going on. But FileEntry@6e470ce1 is probably the result of the toString method of FileEntry. You can overwrite that to return whatever you want, as long as it is a String.

本王不退位尔等都是臣 2024-11-17 00:13:10

我不知道为什么你不直接在 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;
    }
}

I am not sure why you wouldn't just implement the toString() method in FileEntry. If you really want a compile error, you can make a base abstract class like:

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

Then create your class like this, it will create a compile error that you have to implement the toString() method:

public class FileEntry extends ForceImplementToString {
    private String name;
    public FileEntry (String name) {
        this.name = name;
    }
}
揽月 2024-11-17 00:13:10

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

您无法阻止这种情况发生。

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

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

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

The Object class has a toString() that is inherited by every Class in Java (since very class derives from Object). This toString() will be called (unless it is overridden, in which case that particular object's overridden toString() will be called).

There is nothing you can do to prevent this from happening.

On another note, what does your method look like? If you have public myMethod(String arg) and you call myMethod(new FileEntry()), I'm pretty sure that results in a compile-time error.

Of course, if you have an overloaded method that has Object arg as a parameter, then that's the method that will be called. Internally, this method is probably calling toString() on arg. Also, using an object that is not a string in a string context (for example, if you concatenate it to a string), results in an implicit call to that object's toString() (which can be the overridden one, or the default from from Object).

To get a prettier result from toString(), you should override toString() in the FileEntry class so that it prints something that makes more sense.

夜唯美灬不弃 2024-11-17 00:13: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

I don't think your premise is correct. Java does not automatically convert objects to strings. This code:

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";
    }
}

produces this output from my Java 1.6.0_23 compiler:

Foo.java:4: concat(java.lang.String) in java.lang.String cannot be applied to (Foo)  
            String got = "Concatenated: ".concat(foo);
                                         ^
1 error
德意的啸 2024-11-17 00:13:10

您始终可以下载 java 源代码,并从 Object 中删除 toString()。

You could always download the source for java, and remove toString() from Object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文