在阅读完C#的隐藏特性后,我想知道Java有哪些隐藏特性?
当你不需要StringBuilder
中包含的同步管理时,请使用StringBuilder
而不是StringBuffer
。这将提高应用程序的性能。
对于Java 7的改进甚至比任何隐藏的Java特性都要好:
不要在实例化时使用那些无限的<>语法:
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
// Can now be replaced with this:
Map<String, List<String>> anagrams = new HashMap<>();
在switch语句中应该使用字符串,而不是旧式的C int类型。
String s = "something";
switch(s) {
case "quux":
processQuux(s);
// fall-through
case "foo":
case "bar":
processFooOrBar(s);
break;
case "baz":
processBaz(s);
// fall-through
default:
processDefault(s);
break;
}
这是旧代码:
static void copy(String src, String dest) throws IOException {
InputStream in = new FileInputStream(src);
try {
OutputStream out = new FileOutputStream(dest);
try {
byte[] buf = new byte[8 * 1024];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
} finally {
out.close();
}
} finally {
in.close();
}
}
现在可以用这个更简单的代码来代替它:
static void copy(String src, String dest) throws IOException {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest)) {
byte[] buf = new byte[8192];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}
}
StringBuilder
而不是 StringWriter
?StringBuffer
和 StringBuilder
的 API 相同,但使用 StringWriter
需要进行一些代码更改。 - pjp"const"是一个关键字,但你不能使用它。
注:该段内容已翻译为中文并保留了HTML标签,不包含解释。int const = 1; // "not a statement"
const int i = 1; // "illegal start of expression"
我猜编译器的作者认为它可能在未来被使用,所以最好保留它。
goto
是一样的——保留但未实现)。 - Michael Myers标识符可以包含像umlauts这样的外语字符:
不必写成:
String title="";
有人可能会写:
String Überschrift="";
\u00dcberschrift = "OK";
- user85421我可以添加Scanner对象。它是最适合解析的工具。
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();
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 Slow
真实时间 0分15.397秒
$ time java Slow
真实时间 0分20.012秒
$ time java Slow
真实时间 0分18.645秒
平均时间: 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 Fast
real 0m12.003s
$ time java Fast
real 0m9.840s
$ time java Fast
real 0m9.686s
平均时间:10.509秒
引用类作用域变量需要更多的字节码,而方法作用域变量则不然。在关键循环之前添加方法调用几乎不会增加额外开销(并且编译器可能会将调用内联)。
这种技术(始终使用访问器)的另一个优点是它消除了Slow类中的潜在错误。如果第二个线程不断将 的值重置为0(例如通过调用slow.setI(0)
),那么Slow类永远无法结束其循环。调用访问器并使用本地变量消除了这种可能性。
在Linux 2.6.27-14上使用J2SE 1.6.0_13进行测试。
你选择的编码方式如何处理属性文件?以前,当你加载Properties时,你提供了一个InputStream,load()
方法将其解码为ISO-8859-1。你实际上可以将文件存储在其他编码中,但是在加载后要使用类似于以下的恶心的hack来正确解码数据:
String realProp = new String(prop.getBytes("ISO-8859-1"), "UTF-8");
但是,从JDK 1.6开始,有一个load()
方法可以接受Reader而不是InputStream,这意味着您可以从一开始就使用正确的编码(还有一个store()
方法可以接受Writer)。对我来说,这似乎是个很大的问题,但它似乎是悄悄地被添加到JDK中的,没有任何声势。我几周前才偶然发现它,而快速的谷歌搜索只找到了一次提到它的轻描淡写的提及。
\uXXXX
转义序列。最好在编辑文件之后部署之前使用 native2ascii
进行转换,或者使用 load()
方法的读取器变体。 - Paŭlo Ebermann让我感到惊讶的是自定义序列化机制。
虽然这些方法是私有的!!,但是在对象序列化期间,JVM会“神秘地”调用它们。
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
您可以创建自己的自定义序列化方式以使其更加“安全、快速、稀有、易用等等”。
如果必须通过节点传递大量信息,则应考虑此方法。可以更改序列化机制以发送数据的一半。很多时候,瓶颈不在平台上,而在于通过网络发送的数据量,这样做可能会节省成千上万美元的硬件费用。
这里有一篇文章。 http://java.sun.com/developer/technicalArticles/Programming/serialization/
大多数人不知道他们可以克隆一个数组。
int[] arr = {1, 2, 3};
int[] arr2 = arr.clone();
Object
上调用 clone
。你只需要小心确保该 Object
实现了深度克隆。 - Finbarrclone
方法,只能在公开了该方法的类或当前类的对象上调用。 - Paŭlo Ebermann当人们意识到可以使用反射调用私有方法并访问/更改私有字段时,他们有时会感到有些惊讶...
考虑以下类:
public class Foo {
private int bar;
public Foo() {
setBar(17);
}
private void setBar(int bar) {
this.bar=bar;
}
public int getBar() {
return bar;
}
public String toString() {
return "Foo[bar="+bar+"]";
}
}
import java.lang.reflect.*;
public class AccessibleExample {
public static void main(String[] args)
throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException {
Foo foo=new Foo();
System.out.println(foo);
Method method=Foo.class.getDeclaredMethod("setBar", int.class);
method.setAccessible(true);
method.invoke(foo, 42);
System.out.println(foo);
Field field=Foo.class.getDeclaredField("bar");
field.setAccessible(true);
field.set(foo, 23);
System.out.println(foo);
}
}
Foo[bar=17]
Foo[bar=42]
Foo[bar=23]
setAccessible
调用可能会被安全管理器禁止。 - Paŭlo EbermannJava 6中的注解处理API对于代码生成和静态代码验证非常有前景。