2024-04-20 09:00:01

Java的隐藏特性

在阅读了c#的隐藏特性之后,我想知道Java的隐藏特性有哪些?


当前回答

函子很酷。它们非常接近于函数指针,而这在Java中是不可能的。

Java中的函子

其他回答

列表。subblist返回原始列表的视图

一个有文献记载但鲜为人知的列表特征。这允许您使用反映在原始列表中的更改来处理列表的部分。

列出子列表(int fromIndex, int toIndex)

这种方法消除了显式范围操作的需要(通常存在于数组的那种操作)。任何需要一个列表的操作都可以通过传递一个subblist视图而不是整个列表来用作范围操作。例如,下面的习惯用法从列表中移除一系列元素: 列表。分表(,).clear (); 类似的习惯用法可以用于indexOf和lastIndexOf, Collections类中的所有算法都可以应用于子列表。”

部分功能,部分麻烦:Java的String处理使其“看起来”是原生类型(使用运算符,+,+=)

能写的:

String s = "A";
s += " String"; // so s == "A String"

非常方便,但只是语法糖(即被编译为):

String s = new String("A");
s = new StringBuffer(s).append(" String").toString();

因此,一个对象实例化和2个方法调用一个简单的连接。想象一下以这种方式在循环中构建一个长字符串!?并且StringBuffer的所有方法都声明为同步的。谢天谢地,在Java 5中,他们引入了StringBuilder,它与StringBuffer是一样的,只是没有同步。

这样的循环:

String s = "";
for (int i = 0 ; i < 1000 ; ++i)
  s += " " + i; // Really an Object instantiation & 3 method invocations!

可以(应该)在你的代码中重写为:

StringBuilder buf = new StringBuilder(); // Empty buffer
for (int i = 0 ; i < 1000 ; ++i)
  buf.append(' ').append(i); // Cut out the object instantiation & reduce to 2 method invocations
String s = buf.toString();

并将运行大约80+%比原来的循环! (在我运行的一些基准测试中高达180%)

在Swing中工作时,我喜欢隐藏的Ctrl - Shift - F1特性。

它转储当前窗口的组件树。 (假设您没有将该击键绑定到其他内容。)

javabean属性访问器方法不必以“get”和“set”开头。

甚至Josh Bloch在《Effective Java》中也犯了这个错误。

一个优化技巧,使您的代码更容易维护,更不容易受到并发性错误的影响。

public class Slow {
  /** Loop counter; initialized to 0. */
  private long i;

  public static void main( String args[] ) {
    Slow slow = new Slow();

    slow.run();
  }

  private void run() {
    while( i++ < 10000000000L )
      ;
  }
}

$ time java慢 真正的0 m15.397s $ time java慢 真正的0 m20.012s $ time java慢 真正的0 m18.645s

平均:18.018秒

public class Fast {
  /** Loop counter; initialized to 0. */
  private long i;

  public static void main( String args[] ) {
    Fast fast = new Fast();

    fast.run();
  }

  private void run() {
    long i = getI();

    while( i++ < 10000000000L )
      ;

    setI( i );
  }

  private long setI( long i ) {
    this.i = i;
  }

  private long getI() {
    return this.i;
  }
}

$ time java快速 真正的0 m12.003s $ time java快速 真正的0 m9.840s $ time java快速 真正的0 m9.686s

平均:10.509秒

引用类作用域变量比引用方法作用域变量需要更多的字节码。在关键循环之前添加方法调用几乎不会增加开销(而且编译器可能会内联调用)。

这种技术(总是使用访问器)的另一个优点是它消除了Slow类中的潜在错误。如果第二个线程要不断地将i的值重置为0(通过调用slow. xml)。setI(0),例如),Slow类永远不能结束它的循环。调用访问器并使用局部变量消除了这种可能性。

在Linux 2.6.27-14上使用J2SE 1.6.0_13进行测试。