생성자 또는 외부 생성자 내에서 변수를 초기화해야 하는가?
내가 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
), 왜 코드를 복제하는가?
'Programing' 카테고리의 다른 글
단일 파일 컴프에서 글로벌 Vue 구성 요소에 컨텐츠를 추가할 수 있는가? (0) | 2022.05.04 |
---|---|
CRC16 체크섬 계산 기능 (0) | 2022.05.04 |
vuetify의 중앙 부동 버튼 (0) | 2022.05.03 |
재해석_캐스트 캐스팅 비용 (0) | 2022.05.03 |
Vue-roouter 및 Vuex와 함께 작동하도록 경로 매개 변수를 가져오는 방법 (0) | 2022.05.03 |