在阅读完C#的隐藏特性后,我想知道Java有哪些隐藏特性?
这不是一个真正的特性,但它让我感到好笑,goto
是一个保留字,除了提示javac戳你的眼睛外,什么都不做。只是为了提醒你现在处在OO-land。
你可以定义并调用匿名内部类上的方法。
虽然它们并不那么隐秘,但很少有人知道它们可以被用来在一个类中定义一个新的方法并像这样调用它:
(new Object() {
public String someMethod(){
return "some value";
}
}).someMethod();
这种方法可能不太常见,因为它也不是很有用,你只能在定义它时(或通过反射)调用该方法一次。
strictfp关键字。(虽然我从未在实际应用中看到过它的使用:))
您可以使用以下表示法获取基本类型的类:int.class,float.class等。在进行反射时非常有用。
最终数组可用于从匿名内部类“返回”值(警告,下面是无用的示例):
final boolean[] result = new boolean[1];
SwingUtilities.invokeAndWait(new Runnable() {
public void run() { result[0] = true; }
});
invokeAndWait
,这比 invokeLater
更有用。 - Paŭlo EbermannC风格的 printf() :)
System.out.printf("%d %f %.4f", 3,Math.E,Math.E);
输出: 3 2.718282 2.7183
二分查找(及其返回值)
int[] q = new int[] { 1,3,4,5};
int position = Arrays.binarySearch(q, 2);
类似于C#,如果在数组中找不到'2',则返回负值,但是如果对返回的值进行1's补码,实际上可以获得插入'2'的位置。
在上面的例子中,位置= -2,~位置=1,这是应插入2的位置...它还可以让您在数组中找到“最接近”的匹配项。
我认为这相当巧妙... :)
printf
不是隐藏的,binarySearch
的工作也不是。 - user85421我知道Java 6包含脚本支持,但最近才发现jrunscript,它可以交互式地解释和运行JavaScript(以及其他脚本语言,如Groovy),有点像Python shell或Ruby中的irb。
既是特性,又是麻烦:Java中的字符串处理使其“看起来”像原生类型(对其使用操作符+、+=)
能够编写以下代码:
String s = "A";
s += " String"; // so s == "A String"
很方便,但只是语法糖(即被编译成):
String s = new String("A");
s = new StringBuffer(s).append(" String").toString();
因此,对于简单的字符串连接而言,需要进行一个对象实例化和两个方法调用。想象一下在循环中以这种方式构建一个长字符串!?并且所有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%)
"A"
真正的类型是 java.lang.String,尽管它的后备字符数组以不同于动态创建字符串的方式进行分配。 - Donal Fellows反射虽然不算是秘密技术,但其功能极为强大实用。利用简单的Class.forName("...").newInstance()语句创建可配置的类类型非常方便,编写此类工厂实现也十分简单。
我知道这个功能是在1.5版中添加的,但新的枚举类型是一个很棒的功能。不必再使用旧的“int枚举模式”已经极大地帮助了我的一堆代码。查看JLS 8.9可了解更多信息。
今天我重新学习到在Java中$是方法或变量的合法名称。结合静态导入,它可以使代码更具可读性,这取决于您对可读性的看法:
实例变量的final:
对于多线程代码非常有用,使得实例状态和正确性更易于讨论。在工业环境中很少见到它,并且通常没有在Java类中思考。
static {something;}:
用于初始化静态成员(我更喜欢使用一个具有名称的静态方法来进行初始化)。没有被广泛应用。