下面的代码行如何在没有 new 运算符的情况下创建对象



我学到的是,new对于创建对象是强制性的。那么,这行代码(来自java swing)是如何工作的呢?

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

这是因为返回GraphicsEnvironment类型的 getLocalGraphicsEnvironment 方法的static实现。从类本身来看,定义为 -

/**
 * Returns the local <code>GraphicsEnvironment</code>.
 * @return the local <code>GraphicsEnvironment</code>
 */
public static synchronized GraphicsEnvironment getLocalGraphicsEnvironment() {
    if (localEnv == null) {
        localEnv = createGE();
    }
    return localEnv;
}

其中localEnv声明为 -

private static GraphicsEnvironment localEnv;

这是来自createGE()的代码:

private static GraphicsEnvironment createGE() {
    GraphicsEnvironment ge;
    String nm = AccessController.doPrivileged(new GetPropertyAction("java.awt.graphicsenv", null));
    try {
        // long t0 = System.currentTimeMillis();
        Class<GraphicsEnvironment> geCls;
        try {
            // First we try if the bootclassloader finds the requested
            // class. This way we can avoid to run in a privileged block.
            geCls = (Class<GraphicsEnvironment>)Class.forName(nm);
        } catch (ClassNotFoundException ex) {
            // If the bootclassloader fails, we try again with the
            // application classloader.
            ClassLoader cl = ClassLoader.getSystemClassLoader();
            geCls = (Class<GraphicsEnvironment>)Class.forName(nm, true, cl);
        }
        ge = geCls.newInstance();
        // long t1 = System.currentTimeMillis();
        // System.out.println("GE creation took " + (t1-t0)+ "ms.");
        if (isHeadless()) {
            ge = new HeadlessGraphicsEnvironment(ge);
        }
    } catch (ClassNotFoundException e) {
        throw new Error("Could not find class: "+nm);
    } catch (InstantiationException e) {
        throw new Error("Could not instantiate Graphics Environment: "
                        + nm);
    } catch (IllegalAccessException e) {
        throw new Error ("Could not access Graphics Environment: "
                         + nm);
    }
    return ge;
}

虽然它实际上从未直接调用new来创建对象,但它使用反射为您创建图形环境。在这种情况下,对 newInstance() 的调用会创建您正在使用的类的新实例,除非您正在运行无头;此时,它直接使用 new 关键字创建。

相关内容

最新更新