什么是Java Base API中最具误导性的方法?
我最近试图将string文字转换为boolean
,当方法boolean Boolean.getBoolean(String name)
popup自动完成窗口。 还有另外一种方法( boolean Boolean.parseBoolean(String s)
)出现在后面,这导致我search找出这两者之间有什么区别,因为他们似乎都这样做。
事实certificate, Boolean.getBoolean(String name)
实际上做的是检查是否存在给定名称的System
属性(!),以及它的值是否为true
。 我认为这是非常具有误导性的,因为我绝对不会期望Boolean
方法实际上调用了System.getProperty
,只是通过查看方法签名,它确实看起来像(至less对我来说)被用来parsing一个String
作为boolean
。 当然,javadoc说得很清楚,但我仍然认为这个方法有一个误导性的名字,而且它不在正确的位置。 其他原始types的包装,如Integer
也有类似的方法。
另外,它似乎不是一个非常有用的方法属于基础的API,因为我认为这是不是很常见的东西像-Darg=true
。 也许这是一个Java位置面试的好问题:“ Boolean.getBoolean("true")
的输出是什么?” 我相信这些方法的更合适的位置将在System
类,例如, getPropertyAsBoolean
; 但是我仍然认为没有必要在基础API中使用这些方法。 把它们放在像Properties
类这样的东西里是很有意义的,在这种types的转换中非常普遍。
你怎么看待这一切? 另外,如果您还有其他“尴尬”的方法,请将其发布。
NB我知道我可以使用Boolean.valueOf
或Boolean.parseBoolean
将string转换为boolean
,但我只是想讨论一下API的devise。
URL equals()方法比较IP地址,使用networking连接并且是阻止操作!
从javadocs:
如果两个主机名可以parsing为相同的IP地址,则认为两个主机相同; 否则,如果任何一个主机名不能parsing,主机名称必须相同而不考虑大小写; 或者两个主机名都等于null。
由于主机比较需要名称parsing,所以此操作是阻止操作。
注意:equals定义的行为已知与HTTP中的虚拟主机不一致。
改用URI。
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类devise中的一个错误。
刚刚从这里得到这个,关于List
的add
和remove
方法(当用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
String.getBytes()
往往是应用程序中很多愚蠢的字符编码问题的原因,因为它使用底层平台字符编码。
刚刚发现了有关Thread
类interrupted
和interrupted
的方法。 来自javadoc
:
static boolean interrupted() // Tests whether the current thread has been interrupted. boolean isInterrupted() // Tests whether this thread has been interrupted.
问题是interrupted
除了做testing之外实际上清除了中断状态,而中断只是testing状态。
这可能不是最糟糕的方法,但我从来不喜欢这个 :
假设x是已知只包含string的列表。 以下代码可用于将列表转储到新分配的string数组中:
String[] y = x.toArray(new String[0]);
将大小为0的string数组传递给方法对我来说似乎是疯狂和不直观的。
InputStream.read(字节[])
不填充数组; 而是读取任意数量的字节并返回该数字。 你必须循环。 讨厌的,因为它大部分时间适用于小arrays。 我不认为有人第一次使用它是正确的。
一些redditor注意到String.substring导致内存泄漏,因为它在内部不会复制子string,而只是将指针复制到整个string+ offset + length。 所以如果你期望整个string被GC收集,你是拧。
http://www.reddit.com/r/programming/comments/8ydvg/the_dangers_of_stringsubstring/c0au0gj
我的问题是与string的子string方法; 每次使用它,我必须写出“汉堡包”和“汉堡包”.substring(4,8)=“敦促”来记住如何正确使用它
那么,System.setOut()会将该值设置为System的最后一个成员!
我从来没有真正理解为什么JDBC API始终以1开始计数,而Java(和C,C ++,C#,…)Universe的其余部分从0开始。这适用于列号,准备语句中的参数号等。
我同意。 我一直对这些方法感到不舒服。
我甚至在我们的代码库中发现了一个由使用Integer.getInteger()的人来parsing一个string而导致的错误,而不是意识到它正在查找属性。
不幸的是,为了向后兼容的原因,API不可能被删除。
我不确定是否有人仍然使用这个,但是如果出现错误,那么DocumentBuilder.parse()
的错误信息总是“几乎?”内容在prolog中是不允许的。 即使真正的原因是完全的东西。
BigDecimal.setScale(int)一个返回BigDecimal hmmm的setter
Java中的一个难题就是Integer.parseInt(“SomeString”)中的失败仅仅表明存在parsing错误,没有告诉我们“SomeString”是什么。 因此,有时需要进行大量的debugging来找出string是什么。 如果错误信息包含错误的string,追踪问题会更快。
我不会在“最尴尬”的文件,但java.security.MessageDigest.getInstance()给了我一些困惑。
我通常用来看到一个“getInstance()”方法返回一个单例。
如果一个方法要返回一个新的实例,我可能期望看到一个MessageDigestFactory.newInstance(),或者至less在MessageDigest类的newInstance()而不是它们的getInstance()方法。
请参阅: MessageDigest.getInstance()
从我testing过的,MessageDigest.getInstance()每次调用时都会返回一个新的实例。
java.util.Date.getDate()
返回一个数字1-31。 getDayOfMonth()
是解释它的准确方法,而您通常试图记住getTime()
。
不能等待乔达时间接pipe。