在阅读完C#的隐藏特性后,我想知道Java有哪些隐藏特性?
也许最令人惊讶的隐藏功能是 sun.misc.Unsafe 类。
http://www.docjar.com/html/api/ClassLib/Common/sun/misc/Unsafe.java.html
你可以做到以下几点:
顺便说一句:不正确地使用此类将导致 JVM 崩溃。 我不知道哪些 JVM 支持此类,因此它不具备可移植性。
这是我的列表。
我最喜欢(也是最可怕的)隐藏功能是,您可以从未声明要抛出任何异常的方法中抛出已检查的异常。
import java.rmi.RemoteException;
class Thrower {
public static void spit(final Throwable exception) {
class EvilThrower<T extends Throwable> {
@SuppressWarnings("unchecked")
private void sneakyThrow(Throwable exception) throws T {
throw (T) exception;
}
}
new EvilThrower<RuntimeException>().sneakyThrow(exception);
}
}
public class ThrowerSample {
public static void main( String[] args ) {
Thrower.spit(new RemoteException("go unchecked!"));
}
}
public static void main(String[] args) {
throw null;
}
猜一下这个会打印什么:
Long value = new Long(0);
System.out.println(value.equals(0));
public int returnSomething() {
try {
throw new RuntimeException("foo!");
} finally {
return 0;
}
}
以上应该不会让优秀的开发人员感到惊讶。
在Java中,你可以用以下有效的方法声明一个数组:
String[] strings = new String[] { "foo", "bar" };
// the above is equivalent to the following:
String[] strings = { "foo", "bar" };
所以,以下Java代码是完全有效的:
public class Foo {
public void doSomething(String[] arg) {}
public void example() {
String[] strings = { "foo", "bar" };
doSomething(strings);
}
}
以下代码为什么不合法呢?有没有什么有效的理由?
public class Foo {
public void doSomething(String[] arg) {}
public void example() {
doSomething({ "foo", "bar" });
}
}
我认为,上述语法可以有效替代Java 5引入的varargs,并且更加符合先前允许的数组声明。
throw null
应该会导致 NullPointerException
。 - Paŭlo EbermannShutdown Hooks 允许注册一个线程,在JVM结束时创建并启动。因此它是一种“全局jvm终结器”,您可以在此线程中执行有用的操作(例如关闭Java资源,如嵌入式hsqldb服务器)。它可以与 System.exit() 以及 CTRL-C / kill -15 一起使用(但在Unix上无法与kill -9一起使用)。
此外,设置也相当简单。
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
endApp();
}
});;
destroy-method
属性 - 来终止工作子进程。 - Donal Fellows的价值:
new URL("http://www.yahoo.com").equals(new URL("http://209.191.93.52"))
< p >是< code >真的。
(来自Java Puzzlers)
如果你经常进行JavaBean开发,并且使用属性更改支持,通常会编写很多像这样的setter:
public void setFoo(Foo aFoo){
Foo old = this.foo;
this.foo = aFoo;
changeSupport.firePropertyChange("foo", old, aFoo);
}
我最近偶然发现了一篇博客,建议采用更简洁的实现方式,这可以让代码写起来更容易:
public void setFoo(Foo aFoo){
changeSupport.firePropertyChange("foo", this.foo, this.foo = aFoo);
}
实际上,这简化了事情,以至于我能够在Eclipse中调整setter模板,使得方法自动创建。
静态导入可以“增强”语言,以便您可以以类型安全的方式进行优雅的文字操作:
List<String> ls = List("a", "b", "c");
List<Map<String, String>> data = List(Map( o("name", "michael"), o("sex", "male")));
asList
返回的是一个固定大小的基于数组的列表。 - Jeremy虽然不是特别隐蔽,但很有趣。
你可以在没有main方法的情况下拥有一个“Hello, world”程序(尽管会抛出NoSuchMethodError异常)
最初由RusselW在Strangest language feature发布。
public class WithoutMain {
static {
System.out.println("Look ma, no main!!");
System.exit(0);
}
}
$ java WithoutMain
Look ma, no main!!
System.exit(0);
以避免出现难看的异常。 - Donal Fellows如果您未使用默认初始化程序,则Java处理变量定义的一个巧妙技巧。
{ int x;
if(一些条件) x=1;
if(x == 1) ... }
这将在编译时给您一个错误,指出您有一个路径其中 X 没有正确定义。这帮了我几次忙,所以我已经开始考虑像下面这样的默认初始化:
int x=0; String s=null;
是一个不好的模式,因为它会阻止这种有用的检查。
话虽如此,有时很难回避——当它作为默认值时是有意义的,我不再在第一次编辑时加入 = null。
虽然这不是一个真正的隐藏功能,但当我看到它编译成功时,我还是感到非常惊讶:
public int aMethod(){
http://www.google.com
return 1;
}
编译器之所以能够编译该代码,是因为其中的 http://www.google.com 这一行,其中的 "http:" 部分被编译器视为标签,而该行剩余的部分被视为注释。
因此,如果你想写一些奇怪的代码(或混淆代码),只需在其中放置许多 http 地址即可。;-)