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

Joã*_*lva 36 java methods naming-conventions

boolean当方法boolean Boolean.getBoolean(String name)弹出自动完成窗口时,我最近尝试将字符串文字转换为a .之后还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将字符串文字转换为a boolean,但我只是想讨论API设计.

dog*_*ane 43

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

来自javadocs:

如果两个主机名都可以解析为相同的IP地址,则认为两个主机是等效的.否则,如果无法解析任何一个主机名,则主机名必须相等而不考虑大小写; 或两个主机名都等于​​null.

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

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

请改用URI.


Jes*_*per 31

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);
Run Code Online (Sandbox Code Playgroud)

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

cal.set(2009, Calendar.AUGUST, 18);
Run Code Online (Sandbox Code Playgroud)

但是这种方法很容易犯下使用正常月份数1到12的错误.

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

  • 如果Calendar类提供查找功能(当然,支持I18N),那么首先不需要基于零的闹剧.无论如何,大多数程序员习惯于删除或添加一个,以便处理索引但是 - 在一天结束时 - 一个月是一个序数值,从一开始,这个约定已经存在了很长时间它是一个因为这种可怜的理由而忽视惯例的非常糟糕的决定.由于DAY_OF_WEEK值从1到7变得更加烦人! (5认同)
  • 这是在枚举之前设计的 (3认同)
  • 我认为这是另一个来自着名的C API的手工 - 包括月和日之间的不一致. (2认同)

Joã*_*lva 26

刚拿到这一个从这里,关于addremove方法List(参数与时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   
Run Code Online (Sandbox Code Playgroud)

  • @Lumpy你会对int变量产生同样的效果. (2认同)

Jon*_*Jon 11

String.getBytes()
Run Code Online (Sandbox Code Playgroud)

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

  • 更是如此:FileReader甚至没有*一个允许你指定编码的构造函数. (7认同)
  • 来自javadoc:此类的构造函数假定默认字符编码和默认字节缓冲区大小是合适的.要自己指定这些值,请在FileInputStream上构造一个InputStreamReader. (3认同)
  • @gnud:但是`FileReader`的意思是作为一个便利类,它允许你读取文件而不必使用这些类.实际上,`FileReader`**是一个**`InputStreamReader`,它使用`FileInputStream`来查看源代码,因此,它绝对应该允许通过ctor设置`Charset`,就像它的父类一样. (2认同)
  • 有一百个地方Java允许或鼓励你省略字符集.这是不幸的,因为它几乎总会导致你的美国测试人员不会注意到的一个模糊的小错误.平台的"默认编码"比无用更糟糕.是否有标记此用法的Java lint? (2认同)
  • 将字符串传递给String:String.getBytes("UTF8")或使用Charset对象. (2认同)

Joã*_*lva 9

刚刚发现了方法isInterruptedinterrupted课程Thread.来自javadoc:

static boolean interrupted()
// Tests whether the current thread has been interrupted.
boolean isInterrupted()
// Tests whether this thread has been interrupted.
Run Code Online (Sandbox Code Playgroud)

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


Ott*_*ger 7

这可能不是最糟糕的方法,但我从来不喜欢这个:

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

String[] y = x.toArray(new String[0]);
Run Code Online (Sandbox Code Playgroud)

将大小为0的String数组传递给方法看起来很疯狂,对我来说不直观.

  • 实际上,如果编写x.toArray(new String [x.size()]),性能会稍微提高一些.然后它填充你分配和传入的数组,而不是查看传入数组的类型,抛弃它,并创建一个新数组.但我同意,这很尴尬.我会想到,当他们添加模板时,他们会创建一个更干净的,但显然不是. (5认同)
  • 是的,这总是很糟糕,但由于类型擦除,这是推断类型的唯一方法. (3认同)

Mic*_*rdt 6

InputStream.read(字节[])

不填充阵列; 相反,它读取任意数量的字节并返回该数字.你必须循环.令人讨厌,因为它大部分时间都适用于小型阵列.我认为没有人在他们第一次使用它时就做对了.

  • 它的工作方式与C程序员的预期方式完全相同; P (13认同)

may*_*eye 6

一些redditor注意到String.substring会导致内存泄漏,因为在内部它不会复制子字符串,而只是将指针复制到整个字符串+ offset + length.因此,如果您希望GC收集整个字符串,那么您就搞砸了.

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


Jil*_*nee 5

我的问题是使用String的substring方法; 每次我使用它时我都要写出"hamburger"和"hamburger"这个词.substring(4,8)="urge"来记住如何正确使用它

  • 大多数子串/切片/子集API以类似的方式工作,所以我不确定它真的有点令人困惑.我已经开始期望这样的范围在底部是封闭的,但在顶部是敞开的.它使迭代变得更容易. (2认同)

Shi*_*iel 5

好吧,System.setOut()会将值设置为System 的最终成员!!!!

  • IMO,真正的问题是System.{in,out,err}应该是静态方法而不是静态最终成员. (2认同)

mko*_*ler 5

我从来没有真正理解为什么JDBC API始终以1开始计数,而其余的Java(以及C,C++,C#,...)Universe从0开始.这适用于列号,预处理语句中的参数号等.


Avi*_*Avi 4

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

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

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

  • 他们应该尽快弃用它。 (12认同)