Programing

생성자 또는 외부 생성자 내에서 변수를 초기화해야 하는가?

c10106 2022. 5. 3. 21:39
반응형

생성자 또는 외부 생성자 내에서 변수를 초기화해야 하는가?

내가 C++ 지식을 바탕으로 자바를 사용할 때, 나는 다음과 같은 방법으로 변수를 초기화하는 것을 좋아한다.

public class ME {
    private int i;

    public ME() {
         this.i = 100;
    }
}

얼마 후, 나는 습관을 다음으로 바꾼다.

public class ME {
    private int i = 100;

    public ME() {
    }
}

나는 다른 소스 코드를 우연히 발견했고, 몇몇은 1차 컨벤션, 다른 몇몇은 2차 컨벤션을 사용하고 있다.

너희들이 추천하는 컨벤션은 무엇이며 그 이유는 무엇인지 알 수 있을까?

나는 두 번째 스타일(선언+한 번에 초기화)이 우월하다고 생각한다.이유:

  • 변수가 어떻게 초기화되는지 한눈에 알 수 있다.일반적으로 프로그램을 읽고 변수를 발견하면 먼저 프로그램 선언(IDE에서 자동)으로 이동하게 된다.스타일 2에서는 기본값을 바로 볼 수 있다.스타일 1로, 시공자도 살펴봐야 한다.
  • 두 개 이상의 생성자가 있는 경우 초기화를 반복할 필요가 없으며, 초기화를 잊을 수 없다.

물론 초기화 값이 다른 생성자에서 다른 경우(또는 생성자에서 계산된 경우)에는 생성자에서 수행해야 한다.

나는 두 가지 이유로 거의 항상 경쟁사에서 초기화하는 연습(하빗)을 가지고 있는데, 하나는 가독성(청결성)을 더하는 것이고, 두 가지는 한 줄에 있는 것보다 건설업자에게 더 많은 논리 통제가 있다.초기에는 인스턴스 변수가 로직을 요구하지 않더라도, 그것을 생성자에 두는 것은 필요한 경우 미래에 로직을 추가할 수 있는 더 많은 유연성을 제공한다.

위에 언급한 다중 생성자에 대한 우려에 대해서는, 모든 생성자에 대해 동일하게 초기화되는 모든 인스턴스 변수를 초기화한 다음 각 생성자가 첫 번째 라인에서 이()를 호출하는 하나의 no-arg 생성자를 갖는 것으로 쉽게 해결할 수 있다.그것은 당신의 재탕 문제를 해결해주었다.

나는 복잡한 시공자(또는 쓸모없는 시공자)를 피하기 위해 두 번째 시공자를 사용하는 경향이 있다. 또한 나는 이것을 초기화(초기화라고 해도)로 생각하지는 않지만, 디폴트 값을 부여하는 것에 더 가깝다.

예를 들어 두 번째 코드 조각에서 생성자를 제거하고 더 명확한 코드를 가질 수 있다.

만약 당신이 상부나 시공자에서 초기화를 한다면 그것은 큰 차이가 없다.그러나 어떤 경우에는 건설업자에서 초기화하는 것이 타당하다.

class String
{
    char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense.
    String()
    {
        this.arr=new char[0];
    }
    String(char[] arr)
    {
        this.arr=arr;
    }
}

따라서 상황에 따라 상부에서, 때로는 시공자에서 초기화를 해야 할 것이다.

생성자를 사용하지 않고 초기화하는 FYI 기타 옵션:

class Foo
{
    int i;
    static int k;

    //instance initializer block
    {
        //run's every time a new object is created
        i=20;
    }

    //static initializer block
    static{
        //run's only one time when the class is loaded
        k=18;
    }    
} 

첫 번째 방법에서 내가 보는 유일한 문제는 당신이 더 많은 시공사들을 추가할 계획인가 하는 것이다.그러면 당신은 코드를 반복하게 될 것이고 유지보수가능성은 저하될 것이다.

생성자에서 변수를 초기화할 것을 권장한다.그렇기 때문에 개체들이 제대로 구성(초기화)되도록 하기 위함입니다.

어느 쪽이든 통할 것이고, 스타일 문제지만, 나는 멤버 초기화에는 건설사를 선호한다.

한 가지, 필드의 초기화에 관계없이, 사용법.final가능한 경우 한정자는 다중 구간 환경에서 필드 값의 가시성을 보장한다.

예를 들어, 점검된 예외가 포함된 경우 필드 초기화를 사용할 수 없는 경우 초기화에 따라 달라질 수 있다.예를 들어 다음과 같다.

public class Foo {
    FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException
}

체크된 예외를 선언하는 생성자를 포함하지 않는 한 컴파일 시간 오류가 발생하거나, 다음과 같은 작업을 수행하는 수퍼 클래스를 확장하지 않는 경우:

public Foo() throws FileNotFoundException {} 

나는 둘 다 올바른 프로그래밍을 한다고 생각한다.

그러나 나는 당신의 첫 번째 옵션이 객체 지향적인 방식으로 더 정확하다고 생각한다. 왜냐하면 생성자에서는 객체가 생성되는 시점과 변수가 초기화되어야 하는 시점이기 때문이다.

나는 그것이 "By the book" 컨벤션이라고 생각하지만, 그것은 토론을 위해 열려있다.

위키백과

상황에 따라 두 가지 옵션이 모두 정확할 수 있다.

매우 간단한 예는 다음과 같다.여러 생성자가 있는 경우 변수를 모두 동일한 방식으로 초기화하십시오(각 생성자에 대해 x=2 입력).선언 시 변수를 초기화하여 중복성을 방지하는 것이 타당하다.

이런 상황에서 최종 변수를 고려하는 것도 일리가 있다.선언 시 최종 변수가 어떤 값을 가질지 안다면 생성자 외부에서 초기화하는 것이 타당하다.그러나 클래스 사용자가 생성자를 통해 최종 변수를 초기화하려면 생성자가 나올 때까지 초기화를 지연하십시오.

디폴트(채무불이행)에 따라 다르다고 말하고 싶다.예를 들면

public Bar
{
  ArrayList<Foo> foos;
}

나는 그것을 만들 것이다.new ArrayList만약 내가 항상 생각한다면, 건설업자 밖에서foos수 없다.만약Bar유효한 물건이지, 상관하지 않는다.foos무효든 아니든 시공사에 넣어야지

여러분은 동의하지 않을 수도 있고, 그 물체를 유효한 상태로 만드는 것이 건설업자들의 일이라고 말할 수도 있다.그러나 모든 시공자가 정확히 같은 일을 해야 한다는 것이 명백하다면(초기화하다)foos), 왜 코드를 복제하는가?

참조URL: https://stackoverflow.com/questions/3918578/should-i-initialize-variable-within-constructor-or-outside-constructor

반응형