我最近试图将字符串文字转换为布尔值,当方法 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.valueOf
或 Boolean.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.
发布评论
评论(17)
Calendar 类的一个众所周知的问题是月份编号为 0 到 11,而不是 1 到 12。很容易犯这样的错误:
正确的方法是使用月份常量:
但是该方法使得很容易犯使用正常月份数字 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:
The right way to do it is by using constants for the months:
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.
刚刚从这里得到了这个,关于
和
List
的 addremove
方法(当使用Integer
参数化时)。 例如:Just got this one from here, regarding the
add
andremove
methods ofList
(when parameterized withInteger
). For instance:URL equals() 方法比较 IP 地址,使用网络连接,并且是阻塞操作!
来自javadoc:
请改用 URI。
The URL equals() method compares IP addresses, uses a network connection and is a blocking operation!
From the javadocs:
Use URI instead.
通常是应用程序中出现许多愚蠢的字符编码问题的原因,因为它使用底层平台字符编码。
often the cause of lots of stupid character encoding problems in applications because it uses the underlying platform character encoding.
这可能不是最差方法,但我从来不喜欢这个:
将大小为 0 的字符串数组传递给该方法对我来说似乎很疯狂且不直观。
It's probably not the worst method, but I never liked this one:
Passing an String array of the size 0 to the method just seems crazy and unintuitive to me.
刚刚发现有关方法
isInterrupted
和Thread
类的中断
。 来自javadoc
:问题是
interrupted
除了进行测试之外实际上还清除中断状态,而isInterrupted
只是测试状态。Just found out about the methods
isInterrupted
andinterrupted
of classThread
. Fromjavadoc
:The problem is that
interrupted
actually clears the interrupted status besides doing the test, whileisInterrupted
just tests the status.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.
一些 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
那么,System.setOut() 会将值设置为 System 的 final 成员!!!!
Well, System.setOut() will set the value to a final member of System!!!!
我从来没有真正理解为什么 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.
我同意。 我一直对这些方法感到不舒服。
我什至在我们的代码库中发现了一个错误,该错误是由某人使用 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.
我不确定是否有人仍在使用它,但如果出现问题,来自
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.我的问题是 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
BigDecimal.setScale(int) 一个返回 BigDecimal 的 setter 嗯
BigDecimal.setScale(int) a setter that returns a BigDecimal hmmm
我对 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.
我不会将其归档在“最尴尬”下,但 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.
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 remembergetTime()
.Cannot wait for Joda Time to take over.