2024-04-20 09:00:01

Java的隐藏特性

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


当前回答

JDK发行版中的bin目录下的JVisualVM。监视甚至分析任何java应用程序,即使是没有使用任何特殊参数启动的应用程序。仅在Java 6SE JDK的最新版本中。

其他回答

当人们意识到可以使用反射调用私有方法并访问/更改私有字段时,他们有时会有点惊讶……

考虑下面的类:

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]

这并不是一个真正的功能,而是我最近在一些网页上发现的一个有趣的技巧:

class Example
{
  public static void main(String[] args)
  {
    System.out.println("Hello World!");
    http://Phi.Lho.free.fr

    System.exit(0);
  }
}

是一个有效的Java程序(尽管它会生成警告)。 如果你不明白为什么,请看格雷戈里的回答!;-)好吧,这里的语法高亮也给了一个提示!

作为初学者,我非常欣赏Java 6中的JConsole监控软件,它已经为我解决了一些问题,而且我还在不断地寻找它的新用途。

显然JConsole在Java 5中已经有了,但我认为现在它已经改进了,至少现在工作得更稳定了。

Java 5中的JConsole: Java 5中的JConsole

Java 6中的JConsole: Java 6中的JConsole

当你在做它的时候,好好看看本系列中的其他工具: java6故障排除工具

您可以使用Class<T>对象添加泛型类型的运行时检查,当在某个配置文件中创建类且无法为类的泛型类型添加编译时检查时,这非常方便。你不希望类在运行时爆炸,如果应用程序碰巧配置错误,你不希望所有的类都充满了检查的实例。

public interface SomeInterface {
  void doSomething(Object o);
}
public abstract class RuntimeCheckingTemplate<T> {
  private Class<T> clazz;
  protected RuntimeChecking(Class<T> clazz) {
    this.clazz = clazz;
  }

  public void doSomething(Object o) {
    if (clazz.isInstance(o)) {
      doSomethingWithGeneric(clazz.cast(o));
    } else {
      // log it, do something by default, throw an exception, etc.
    }
  }

  protected abstract void doSomethingWithGeneric(T t);
}

public class ClassThatWorksWithStrings extends RuntimeCheckingTemplate<String> {
  public ClassThatWorksWithStrings() {
     super(String.class);
  }

  protected abstract void doSomethingWithGeneric(T t) {
    // Do something with the generic and know that a runtime exception won't occur 
    // because of a wrong type
  }
}

当你不需要StringBuilder中包含的同步管理时,使用StringBuilder代替StringBuffer。它将提高应用程序的性能。

Java 7的改进甚至比任何隐藏的Java特性都要好:

菱形语法:Link

不要在实例化时使用那些infinite <>语法:

Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

// Can now be replaced with this:

Map<String, List<String>> anagrams = new HashMap<>();

switch中的字符串:Link

在switch中使用String,而不是old-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;
}

自动资源管理Link

这段旧代码:

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);
    }
}