Использует ли Java неявно конструктор (или объект) с оператором new?

Сегодня я узнал, что вы можете использовать new оператор рядом с разделителем (.или "оператор точки"). Это заставило меня задуматься, неявно ли Java использует одну и ту же технику для всех случаев появления нового оператора.

Следующий оператор создает новый "объект InnerClass". Это делается с помощью нового объекта ParentClass, используя .new, Тем не менее, первый new Оператору в этом утверждении не предшествует конструктор (или объект). Итак, Java добавляет один во время компиляции? Я попытался явно добавить один (Main()) к этому утверждению, но код не будет компилироваться.

ParentClass.InnerClass ic = new ParentClass().new InnerClass();

3 ответа

Решение

Форма

someObject.new InnerClass()

используется только для внутренних классов. Экземпляры внутреннего класса должны быть связаны с экземпляром включающего их класса. Часто включающий экземпляр this, отрицая необходимость точечной нотации, но когда вы хотите явно создать экземпляр внутреннего класса, связанного с другим объектом, вы используете приведенный выше синтаксис.

Большинство классов в Java не являются внутренними классами. Нет необходимости во включающем экземпляре, и, следовательно, Java не вставляет неявно new Something() прежде всего new звонки. (Если бы он сделал, он должен был бы вставить new Something() перед вызовами, которые он вставил, и new Something() до тех, и вы не могли ничего построить вообще.)

Внешние классы и статические внутренние классы могут быть созданы самостоятельно, без каких-либо родительских элементов. Нестатические внутренние классы должны быть частью родительского элемента. Поскольку концепция родительского элемента не существует для внешних и статических классов, нет возможности иметь ссылку на этот родительский элемент.

Эта форма предназначена для того, чтобы вы могли создать внешний и внутренний объект за один шаг и просто сохранить ссылку на внутренний. Я никогда не пользовался этим, но удобно знать, что он существует.

Я не смотрел на внутренности этого, но давайте сначала предположим, что компилятор добавляет объект для продолжения нового во время компиляции. Это будет означать, что все наши классы являются внутренними классами другого класса. Так как они не объявлены в другом классе, это не так. Итак: нет, это не добавляет что-то подобное во время компиляции.

На самом деле, давайте разберемся с этим.

public class Outer {

    String strHello = "Hello ^^";

    public void printHello() {
        System.out.println(strHello);
    }

    public static void main(String[] args) {

        // This will print: Hello ^^
        Outer outer = new Outer();
        outer.printHello();

        // This will print: Hello ^^
        new Outer().printHello();
    }
}

Полагаю, вы уже видели такой код раньше. Это просто вызов метода экземпляра класса. Точечная запись также может использоваться для доступа к переменным и внутренним классам. Выше мы использовали его для метода экземпляра. Используя ключевое слово static позволяет совместно использовать методы и переменные для всех экземпляров класса или даже отдельных классов.

public class Outer {

    static String strHello = "Hello ^^";

    public static void printHello() {
        System.out.println(strHello);
    }

    static class StaticInner {
    }

    static class Inner {
    }

    public static void main(String[] args) {

        // Prints: Hello ^^
        Outer.printHello();

        // Constructs a new Example.StaticInner
        Outer.StaticInner inner = new Outer.StaticInner();

        // Constructs a new Outer.Inner     
        Outer.Inner inner = new Example().new Inner();

        // Constructs a new Outer.Inner
        Example ex = new Example();
        Outer.Inner inner = ex.new Inner();
    }
}

Приведенный выше код использует статический внутренний класс, чтобы надеяться продемонстрировать, что внутренний конструктор похож на любой другой конструктор. Но, поскольку он находится внутри другого класса, нам нужно получить к нему доступ через другой (внешний) класс. Если это не статический внутренний класс, тогда мы должны использовать экземпляр для доступа к нему из-за модификаторов доступа.

Другие вопросы по тегам