UFO ET IT

Java에는 C ++와 같은 이니셜 라이저 목록이없는 이유는 무엇입니까?

ufoet 2021. 1. 12. 08:09
반응형

Java에는 C ++와 같은 이니셜 라이저 목록이없는 이유는 무엇입니까?


C ++에서는 생성자가 실행되기 전에 이니셜 라이저 목록을 사용하여 클래스의 필드를 초기화 할 수 있습니다. 예를 들면 :

Foo::Foo(string s, double d, int n) : name(s), weight(d), age(n) {
    // Empty; already handled!
}

Java에 유사한 기능이없는 이유가 궁금합니다. 에 따르면 제 1 권 : 코어 자바 :

C ++는이 특수 구문을 사용하여 필드 생성자를 호출합니다. Java에서는 객체에 하위 객체가없고 다른 객체에 대한 포인터 만 있기 때문에 필요하지 않습니다.

내 질문은 다음과 같습니다.

  1. "객체에 하위 객체가 없기 때문에"란 무엇을 의미합니까? 나는 하위 객체가 무엇인지 이해하지 못합니다. 슈퍼 클래스를 확장하는 서브 클래스의 인스턴스화를 의미합니까?

  2. Java에 C ++와 같은 이니셜 라이저 목록이없는 이유는 모든 필드가 Java에서 기본적으로 이미 초기화되어 있고 Java가 super키워드를 사용 하여 super (또는 C ++ lingo의 기본) 클래스 생성자를 호출 하기 때문 이라고 가정합니다. . 이 올바른지?


C ++에서는 Java에 존재하지 않거나 Java에서 다르게 작동하는 몇 가지 언어 기능 때문에 이니셜 라이저 목록이 필요합니다.

  1. const: C ++에서는 const이니셜 라이저 목록에서 할당 할 수없고 초기화해야하는 표시 있는 필드를 정의 할 수 있습니다 . Java에는 final필드가 있지만 final생성자 본문의 필드에 할당 할 수 있습니다 . C ++ const에서 생성자 필드에 할당하는 것은 불법입니다.

  2. 참조 : C ++에서 참조 (포인터와 반대)는 일부 개체에 바인딩하기 위해 초기화되어야합니다. 이니셜 라이저없이 참조를 만드는 것은 불법입니다. C ++에서 이것을 지정하는 방법은 이니셜 라이저 목록을 사용하는 것입니다. 생성자를 먼저 초기화하지 않고 생성자의 본문에있는 참조를 참조하는 경우 초기화되지 않은 참조를 사용하게됩니다. Java에서 객체 참조는 C ++ 포인터처럼 동작하며 생성 후 할당 될 수 있습니다. 기본값은 null그렇지 않습니다.

  3. 직접 하위 객체 . C ++에서 객체는 객체를 필드로 직접 포함 할 수 있지만 Java 객체는 해당 객체에 대한 참조 만 보유 할 수 있습니다 . 즉, C ++에서 a가있는 객체를 string멤버로 선언하면 해당 문자열의 저장 공간이 객체 자체의 공간에 직접 빌드되는 반면 Java에서는 다른 항목에 대한 참조를위한 공간 만 얻습니다.String다른 곳에 저장된 객체. 결과적으로 C ++는 이러한 하위 객체에 초기 값을 제공 할 수있는 방법을 제공해야합니다. 그렇지 않으면 초기화되지 않은 상태로 유지됩니다. 기본적으로 해당 유형에 대한 기본 생성자를 사용하지만 다른 생성자를 사용하거나 기본 생성자를 사용할 수없는 경우 이니셜 라이저 목록에서이를 우회 할 수 있습니다. Java에서는 참조가 기본적으로로 설정되므로 이에 대해 걱정할 필요가 없습니다. null그런 다음 실제로 참조하기를 원하는 객체를 참조하도록 할당 할 수 있습니다. 기본이 아닌 생성자를 사용하려면 특별한 구문이 필요하지 않습니다. 적절한 생성자를 통해 초기화 된 새 객체에 대한 참조를 설정하기 만하면됩니다.

Java가 이니셜 라이저 목록을 원하는 경우 (예 : 수퍼 클래스 생성자를 호출하거나 해당 필드에 기본값을 제공하기 위해), 이는 두 가지 다른 언어 기능을 통해 처리됩니다. super수퍼 클래스 생성자를 호출 하는 키워드와 Java 객체가 선언 된 지점에서 필드 기본값을 제공합니다. C ++에는 다중 상속이 있기 때문에 단일 super키워드를 갖는 것은 단일 기본 클래스를 명확하게 참조하지 않으며 C ++ 11 이전에는 C ++가 클래스에서 기본 이니셜 라이저를 지원하지 않았고 이니셜 라이저 목록에 의존해야했습니다.

도움이 되었기를 바랍니다!


C ++

차이가 있습니다

ClassType t(initialization arguments);

ClassType * pt;

후자는 초기화 할 필요가 없습니다 (NULL로 설정). 전자는 그렇습니다. 정수로 생각하십시오. 당신은 값없이 int를 가질 수 없습니다, 하지만 당신은 값없이 INT 포인터를 가질 수 있습니다.

따라서 다음과 같은 경우 :

class ClassType
{
    OtherClass value;
    OtherClass * reference;
};

그런 다음 선언 :

ClassType object;

자동의 인스턴스 생성 OtherClass에를 value. 따라서 OtherClass초기화가있는 경우 ClassType생성자 에서 수행해야합니다 . 그러나은 reference포인터 (메모리의 주소) 일 뿐이며 초기화되지 않은 상태로 남아있을 수 있습니다. 당신의 인스턴스 싶은 경우에 OtherClass사용합니다

object.reference = new OtherClass(initialization arguments);

자바

단지

class ClassType
{
    OtherClass reference;
}

이것은 C ++의 포인터와 동일합니다. 이 경우 다음을 수행합니다.

ClassType object = new ClassType();

You don't automatically create an instance of OtherClass. Therefore, you don't have to initialize anything in the constructor unless you want to. When you want an object of OtherClass you can use

object.reference = new OtherClass();

Because Java does not need them to allow initialization of fields whose type has no zero-value.

In C++

class C {
  D d;
}

without a member initializer for d, D::D() will be called which makes it impossible to initialize the field if there is no zero-type for D. This can happen when D::D() is explicitly declared private.

In Java, there is a known zero-value for all reference types, null, so a field can always be initialized.

Java also does a bunch of work to make sure* that all final fields are initialized before first use and before the constructor ends, so while Java has a requirement like C++'s const field initialization requirement, it just overloads this.fieldName = <expression> in the constructor body to mean field initialization.

  • : modulo exceptions thrown in the ctor, overridden method calls from the base class, etc.

ReferenceURL : https://stackoverflow.com/questions/7154654/why-doesnt-java-have-initializer-lists-like-in-c

반응형