Java Base API 中最具误导性的方法是什么?

发布于 2024-08-01 23:32:32 字数 1581 浏览 4 评论 0 原文

我最近试图将字符串文字转换为布尔值,当方法 boolean Boolean.getBoolean(String name) 从自动完成窗口中弹出。 还有另一种方法(boolean Boolean.parseBoolean(String s)) 紧随其后出现,这导致我搜索以找出这两者之间的区别,因为它们似乎都做了相同的。

事实证明,Boolean.getBoolean(String name) 真正做的是检查给定名称是否存在 System 属性 (!),以及它是否存在值为true。 我认为这是非常误导的,因为我绝对不希望 Boolean 的方法实际上调用 System.getProperty,只需查看方法签名,它看起来(至少对我来说)确实应该用于将 String 解析为 boolean。 当然,javadoc 清楚地说明了这一点,但我仍然认为该方法的名称具有误导性,并且位置不正确。 其他原始类型包装器,例如Integer,也有类似的方法。

另外,它似乎不是一个属于基础 API 的非常有用的方法,因为我认为像 -Darg=true 这样的东西并不常见。 也许对于 Java 职位面试来说这是一个很好的问题:“Boolean.getBoolean("true") 的输出是什么?”。 我相信这些方法更合适的位置是 System 类,例如getPropertyAsBoolean; 但同样,我仍然认为没有必要在基础 API 中包含这些方法。 将它们放在像 Properties 类中是有意义的,在该类中进行这种类型的转换非常常见。

您对这一切有何看法?此外,如果您还知道其他“尴尬”的方法,请发布。

NB 我知道我可以使用 Boolean.valueOfBoolean.parseBoolean 将字符串文字转换为 boolean,但我只是想讨论 API 设计。

I was recently trying to convert a string literal into a boolean, when the method boolean Boolean.getBoolean(String name) popped out of the auto-complete window. There was also another method (boolean Boolean.parseBoolean(String s)) appearing right after, which led me to search to find out what were the differences between these two, as they both seemed to do the same.

It turns out that what Boolean.getBoolean(String name) really does is to check if there exists a System property (!) of the given name and if its value is true. I think this is very misleading, as I'm definitely not expecting that a method of Boolean is actually making a call to System.getProperty, and just by looking at the method signature, it sure looks (at least to me) like it should be used to parse a String as a boolean. Sure, the javadoc states it clearly, but I still think the method has a misleading name and it is not in the right place. Other primitive type wrappers, such as Integer also have a similar method.

Also, it doesn't seem to be a very useful method to belong in the base API, as I think it's not very common to have something like -Darg=true. Maybe it's a good question for a Java position interview: "What is the output of Boolean.getBoolean("true")?". I believe a more appropriate place for those methods would be in the System class, e.g., getPropertyAsBoolean; but again, I still think it's unnecessary to have these methods in the base API. It'd make sense to have them in something like the Properties class, where it's very common to do this type of conversions.

What do you think of all this? Also, if there's another "awkward" method that you're aware of, please post it.

N.B. I know I can use Boolean.valueOf or Boolean.parseBoolean to convert a string literal into a boolean, but I'm just looking to discuss the API design.

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

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

发布评论

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

评论(17

拥抱我好吗 2024-08-08 23:32:32

Calendar 类的一个众所周知的问题是月份编号为 0 到 11,而不是 1 到 12。很容易犯这样的错误:

Calendar cal = Calendar.getInstance();

// Set date to August 18, 2009? WRONG! Sets the date to September 18, 2009!
cal.set(2009, 8, 18);

正确的方法是使用月份常量:

cal.set(2009, Calendar.AUGUST, 18);

但是该方法使得很容易犯使用正常月份数字 1 到 12 的错误。

我认为这是 Calendar 类设计中的一个错误。

One well-known problem with the Calendar class is that months are numbered 0 to 11 instead of 1 to 12. It's very easy to make a mistake like this:

Calendar cal = Calendar.getInstance();

// Set date to August 18, 2009? WRONG! Sets the date to September 18, 2009!
cal.set(2009, 8, 18);

The right way to do it is by using constants for the months:

cal.set(2009, Calendar.AUGUST, 18);

But the method makes it much too easy to make the mistake of using the normal month numbers 1 to 12.

I regard this as a mistake in the design of the Calendar class.

无妨# 2024-08-08 23:32:32

刚刚从这里得到了这个,关于 List 的 addremove 方法(当使用 Integer 参数化时)。 例如:

List<Integer> l = new ArrayList<Integer>();
l.add(20);
l.remove(20); // throws ArrayIndexOutOfBoundsException, because it will try to access index 20
l.remove(new Integer(20)); // this works   

Just got this one from here, regarding the add and remove methods of List (when parameterized with Integer). For instance:

List<Integer> l = new ArrayList<Integer>();
l.add(20);
l.remove(20); // throws ArrayIndexOutOfBoundsException, because it will try to access index 20
l.remove(new Integer(20)); // this works   
书信已泛黄 2024-08-08 23:32:32

URL equals() 方法比较 IP 地址,使用网络连接,并且是阻塞操作!

来自javadoc:

如果两个主机名可以是相同的,则两个主机被认为是等效的
解决
进入相同的IP地址; 否则,如果任一主机名不能是
解决后,主机名必须相同,不考虑大小写; 或两者
主机名等于 null。

由于主机比较需要名称解析,因此此操作是
阻塞操作。

注意:已知 equals 的定义行为
与 HTTP 中的虚拟主机不一致。

请改用 URI。

The URL equals() method compares IP addresses, uses a network connection and is a blocking operation!

From the javadocs:

Two hosts are considered equivalent if both host names can be
resolved
into the same IP addresses; else if either host name can't be
resolved, the host names must be equal without regard to case; or both
host names equal to null.

Since hosts comparison requires name resolution, this operation is a
blocking operation.

Note: The defined behavior for equals is known to
be inconsistent with virtual hosting in HTTP.

Use URI instead.

夜吻♂芭芘 2024-08-08 23:32:32
String.getBytes()

通常是应用程序中出现许多愚蠢的字符编码问题的原因,因为它使用底层平台字符编码。

String.getBytes()

often the cause of lots of stupid character encoding problems in applications because it uses the underlying platform character encoding.

过期以后 2024-08-08 23:32:32

这可能不是最差方法,但我从来不喜欢这个

假设 x 是一个已知仅包含字符串的列表。 以下代码可用于将列表转储到新分配的字符串数组中:

String[] y = x.toArray(new String[0]);

将大小为 0 的字符串数组传递给该方法对我来说似乎很疯狂且不直观。

It's probably not the worst method, but I never liked this one:

Suppose x is a list known to contain only strings. The following code can be used to dump the list into a newly allocated array of String:

String[] y = x.toArray(new String[0]);

Passing an String array of the size 0 to the method just seems crazy and unintuitive to me.

少年亿悲伤 2024-08-08 23:32:32

刚刚发现有关方法 isInterruptedThread 类的中断。 来自javadoc

static boolean interrupted()
// Tests whether the current thread has been interrupted.
boolean isInterrupted()
// Tests whether this thread has been interrupted.

问题是interrupted除了进行测试之外实际上还清除中断状态,而isInterrupted只是测试状态。

Just found out about the methods isInterrupted and interrupted of class Thread. From javadoc:

static boolean interrupted()
// Tests whether the current thread has been interrupted.
boolean isInterrupted()
// Tests whether this thread has been interrupted.

The problem is that interrupted actually clears the interrupted status besides doing the test, while isInterrupted just tests the status.

妄司 2024-08-08 23:32:32

InputStream.read(byte[ ])

不填充数组; 相反,它读取任意数量的字节并返回该数字。 你必须循环。 令人讨厌的是,因为它在大多数情况下对于小型数组都可以正常工作。 我认为没有人在第一次使用它时就能正确理解这一点。

InputStream.read(byte[])

Doesn't fill the array; instead it reads an arbitrary number of bytes and returns that number. You have to loop. Nasty, because it works correctly for small arrays most of the time. I don't think anyone gets this right the first time they use it.

临走之时 2024-08-08 23:32:32

一些 redditor 注意到 String.substring 会导致内存泄漏,因为它在内部不会复制子字符串,而只是复制指向整个字符串的指针 + 偏移量 + 长度。 因此,如果您希望 GC 收集整个字符串,那么您就完蛋了。

http://www.reddit.com/r/programming/comments/8ydvg /the_dangers_of_stringsubstring/c0au0gj

Some redditor noticed that String.substring leads to memory leaks, because internally it does not copy substring, but just copies pointer to whole string + offset + length. So if you expected whole string to be collected by GC, you are screwed.

http://www.reddit.com/r/programming/comments/8ydvg/the_dangers_of_stringsubstring/c0au0gj

苦妄 2024-08-08 23:32:32

那么,System.setOut() 会将值设置为 System 的 final 成员!!!!

Well, System.setOut() will set the value to a final member of System!!!!

内心激荡 2024-08-08 23:32:32

我从来没有真正理解为什么 JDBC API 始终从 1 开始计数,而 Java(以及 C、C++、C#...)宇宙的其余部分从 0 开始。这适用于准备好的语句中的列号、参数号等。

I never really understood why the JDBC API consistently starts counting with 1, while the rest of the Java ( and C, C++, C#, ...) universe starts at 0. This applies for column numbers, parameter numbers in prepared statements etc.

不…忘初心 2024-08-08 23:32:32

我同意。 我一直对这些方法感到不舒服。

我什至在我们的代码库中发现了一个错误,该错误是由某人使用 Integer.getInteger() 解析字符串而没有意识到它正在查找属性引起的。

当然,不幸的是,出于向后兼容性的原因,API 无法被删除。

I agree. I've always been uncomfortable with those methods.

I've even found a bug in our code base that was caused by someone using Integer.getInteger() to parse a string, not realizing that it was looking up the property.

Unfortunately, of course, there is no way that the API can ever be removed, for backwards-compatibility reasons.

等风来 2024-08-08 23:32:32

我不确定是否有人仍在使用它,但如果出现问题,来自 DocumentBuilder.parse() 的错误消息(几乎?)总是“序言中不允许内容”。 即使真正的原因完全是别的东西。

I'm not sure if anyone still uses this but the error message from DocumentBuilder.parse() if something goes wrong is (almost?) always "Content is not allowed in prolog." even if the real reason was something else entirely.

天邊彩虹 2024-08-08 23:32:32

我的问题是 String 的 substring 方法; 每次使用它时,我都必须写出单词“hamburger”和“hamburger”。substring(4,8) =“urge”以记住如何正确使用它

my issue is with String's substring method; every time I use it I have to write out the word "hamburger" and "hamburger".substring(4,8) = "urge" to remember how to use it correctly

蓝眸 2024-08-08 23:32:32

BigDecimal.setScale(int) 一个返回 BigDecimal 的 setter 嗯

BigDecimal.setScale(int) a setter that returns a BigDecimal hmmm

不再让梦枯萎 2024-08-08 23:32:32

我对 Java 的一大不满是,Integer.parseInt("SomeString") 中的失败仅仅表明存在解析错误,无法告诉我们“SomeString”是什么。
因此,有时需要进行大量调试才能找出字符串是什么。 如果错误消息包含错误的字符串,那么追踪问题会更快。

One of my pet peeves with Java is the fact that a failure in Integer.parseInt("SomeString") merely states that there was a parse error, failing to tell us what the "SomeString" was.
Because of this, it is sometimes necessary to do loads of debugging to find out what the string was. If the error mesage included the erroneous string, tracking down the problem would be much quicker.

雪若未夕 2024-08-08 23:32:32

我不会将其归档在“最尴尬”下,但 java.security.MessageDigest.getInstance() 给了我一些困惑。

我通常习惯于看到“getInstance()”方法返回一个单例。

如果一个方法要返回一个新实例,我可能期望看到一个 MessageDigestFactory.newInstance(),或者至少在 MessageDigest 类上看到一个 newInstance(),而不是它们的 getInstance() 方法。

请参阅: MessageDigest .getInstance()

根据我的测试,MessageDigest.getInstance() 每次被调用时都会返回一个New 实例。

I wouldn't file it under "Most Awkward", but java.security.MessageDigest.getInstance() gave me some confusion.

I'm typically used to see a "getInstance()" method return a Singleton.

If a method is to return a New Instance, i might expect to see a MessageDigestFactory.newInstance(), or at the very least a newInstance() on the MessageDigest class instead of their getInstance() method.

See: MessageDigest.getInstance()

From what I've tested, MessageDigest.getInstance() returns a New Instance, every single time it's invoked.

谈情不如逗狗 2024-08-08 23:32:32

java.util.Date.getDate() 返回一个数字,1-31。 getDayOfMonth() 是解释它的准确方法,而您通常试图记住 getTime()

等不及乔达时间接管了。

java.util.Date.getDate() returned a number, 1-31. getDayOfMonth() is the accurate way to explain it, whereas you were usually trying to remember getTime().

Cannot wait for Joda Time to take over.

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