2024-04-20 09:00:01

Java的隐藏特性

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


当前回答

前面已经提到,final数组可用于将变量传递给匿名内部类。

另一种更好、更简洁的方法是使用java.util.concurrent.atomic包中的AtomicReference(或AtomicBoolean/AtomicInteger/…)类。

这样做的好处之一是,这些类还提供了compareAndSet这样的方法,如果要创建几个可以修改同一个变量的线程,这个方法可能很有用。


另一个有用的相关模式:

final AtomicBoolean dataMsgReceived = new AtomicBoolean(false);
final AtomicReference<Message> message = new AtomicReference<Message>();
withMessageHandler(new MessageHandler() {
    public void handleMessage(Message msg) {
         if (msg.isData()) {
             synchronized (dataMsgReceived) {
                 message.set(msg);
                 dataMsgReceived.set(true);
                 dataMsgReceived.notifyAll();
             }
         }
    }
}, new Interruptible() {
    public void run() throws InterruptedException {
        synchronized (dataMsgReceived) {
            while (!dataMsgReceived.get()) {
                dataMsgReceived.wait();
            }
        }
    }
});

在这个特殊的例子中,我们可以简单地等待message变成非空,但是null通常是一个有效值,然后你需要使用一个单独的标志来完成等待。

上面的waitMessageHandler(…)是另一个有用的模式:它在某个地方设置了一个处理程序,然后开始执行可能抛出异常的Interruptible,然后在finally块中删除该处理程序,如下所示:

private final AtomicReference<MessageHandler> messageHandler = new AtomicReference<MessageHandler>();
public void withMessageHandler(MessageHandler handler, Interruptible logic) throws InterruptedException {
    synchronized (messageHandler) {
        try {
            messageHandler.set(handler);
            logic.run();
        } finally {
            messageHandler.set(null);
        }
    }
}

这里我假设messageHandler的handleMessage(…)方法在接收到消息时被另一个线程调用。messageHandler不能简单地为messageHandler类型:这样您将同步一个正在变化的变量,这显然是一个错误。

当然,它不需要是InterruptedException,它可以是IOException之类的东西,或者在特定代码段中有意义的任何东西。

其他回答

SwingWorker用于轻松管理后台线程的用户界面回调。

Self-bound泛型:

class SelfBounded<T extends SelfBounded<T>> {
}

http://www.artima.com/weblogs/viewpost.jsp?thread=136394

实例变量的Final:

对多线程代码非常有用,它使争论实例状态和正确性变得容易得多。在工业环境中还没见过很多,在java类中也没想过。


静态{东西;}:

用于初始化静态成员(我也喜欢用静态方法来做它(因为它有一个名称)。没有思想。

语言级assert关键字。

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

Java中的函子