2017-01-25 3 views
-3

Что я узнал, так это то, что новое является обязательным для создания объекта. Итак, как эта строка кода (из java swing) работает?Как следующая строка кода может создать объект без нового оператора?

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
+5

Это метод вызова. Что-то внутри этого метода знает, как получить или создать объект GraphicsEnvironment и вернуть его вам. Метод берет на себя ответственность за то, как делается объект; вы его не создаете. – khelwood

+0

Вы не _creating_ объект; эта функция есть. – SLaks

+0

, поэтому класс GraphicsEnvironment должен иметь модификатор «static», поскольку методы только статических классов можно вызвать, используя непосредственно имя класса. – trotsky

ответ

0

То есть из-за static реализации getLocalGraphicsEnvironment метода, который возвращает тип GraphicsEnvironment. Из class itself, definition, как -

/** 
* 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; 
+0

Но как же это * создать объект? ;) – Kayaman

+0

yeah..exactly..the метод должен тот же код для создания объекта, правильно? – trotsky

+0

'createGE()' это то, что делает это. Короче говоря, просто потому, что вы не видите, что новый оператор не означает, что он не называется где-то вниз по цепочке вызовов методов. Хотя в этом случае новое никогда не вызывается напрямую, так как объект создается с помощью отражения – Brendan

0

Вот код из 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 создать объект , он делает это, используя рефлексию для создания GraphicsEnvironment для вас. В этом случае вызов newInstance() создает новый экземпляр класса, который вы используете, если вы используете Headless; в этот момент он создается напрямую с помощью ключевого слова new.

+0

еще раз спасибо – trotsky

Смежные вопросы