可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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.
回答2:
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.
回答3:
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
回答4:
String.getBytes()
often the cause of lots of stupid character encoding problems in applications because it uses the underlying platform character encoding.
回答5:
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.
回答6:
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.
回答7:
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.
回答8:
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
回答9:
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
回答10:
Well, System.setOut() will set the value to a final member of System!!!!
回答11:
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.
回答12:
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.
回答13:
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.
回答14:
BigDecimal.setScale(int) a setter that returns a BigDecimal hmmm
回答15:
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.
回答16:
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.
回答17:
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.