2009-11-24 3 views
4

생성자 내부에서 파일 객체를 초기화해야하고 예외를 처리하려면 throws을 사용하는 것이 효율적입니까? 아니면 try/catch을 사용해야합니까?생성자에서 throw를 사용할 수 있습니까?

+0

관련 항목 : http://stackoverflow.com/questions/1183531/how-much-work-should-the-constructor-for-an-html-parsing-class-do –

답변

13

생성자에서 예외를 발생시키는 것이 좋습니다. 나는 Java 라이브러리 클래스 중 일부가 그렇게한다는 것을 안다. (한 가지 예를 들면 URI). 알 수 없거나 유효하지 않은 상태의 객체를 반환하는 것보다 예외를 throw하는 것이 더 좋습니다.

+3

'URL' 클래스는 나쁜 코드 이외의 다른 좋은 예가 아닙니다. 예를 들어, 'equals' 메서드는 인터넷에 연결되어 있는지 여부에 따라 다른 값을 반환합니다. (그냥 편이 아니라면 답이 좋습니다) – abyx

+0

@abyx : 이제 언급 했으니, 전적으로 동의합니다 URL에 대해. URI 대신 예제를 사용하여 내 대답을 변경했습니다. 감사. –

+0

URI/URL에 주목해야 할 것이 하나 있는데, 나쁜 입력을 주면 예외가 던져진다. (파일을 열거 나 DNS 조회를 수행하는 것과 같이) 커버 아래에서 뭔가가 일어나기 때문에가 아니라. –

0

당신이 생각하는 생성자에서 초기화되는 것에 관심이 있다면 'throws'와 함께 갈 것입니다.

예외를 숨기면 나중에 문제가 발생할 수 있습니다.

+0

해당 코드 작성 표준이 throwed in 건설자? – i2ijeya

+3

아니요, 그렇지 않습니다. ctor에서 파일을 열지 마십시오. ctor는 내부 상태의 기본 초기화를위한 것입니다. 파일/네트워크/데이터베이스 작업을해야하는 경우 추가 open()/init()/whatever() 메소드에서 수행하십시오. – EricSchaefer

+0

@Eric, 초기화 메소드는 코드 냄새입니다. 객체를 생성 할 때마다 init을 호출해야한다면, init 로직을 생성자에 넣으십시오. 객체 사용자가 init을 호출하여 시스템에 버그를 삽입하는 것을 잊어 버릴 수밖에 없습니다. – Glen

1

일반적으로 생성자에서 많은 작업을 수행하는 것은 좋지 않습니다. 여러 언어로 작성 중에 예외에 대해 수행 할 수있는 작업이 제한 될 수 있습니다.

+0

다른 언어의 제약으로 인해 절대로 Java로해서는 안된다는 말입니까? 이것이 당신의 요점이라면, 나는 동의하지 않는다. –

+1

@Pascal : ** Java **에서 당신을 멈추게하는 것은 아무 것도 없습니다. 원한다면 계속하십시오. 그러나 다른 많은 유용한 언어가 그러한 연습을 방해하기 때문에 다른 언어 (예 : C++)를 사용할 때 명심해야 할 "규칙"이 하나 더 있습니다. ** 당신이 ** 오직 ** 자바 프로젝트에만 도전한다면, 내 의견을 무시해도 좋습니다. – jldupont

+0

"무거워 짐"을 정의하십시오. 나는 이것이 "너무 많이하지 마라"라고 말하는 것 같아요. 얼마나 많은 것을 말하지 않고 말입니다. –

0

물론 자바에서는 실제로 많이 사용됩니다. 예를 들어,

public FileInputStream(String name) 
       throws FileNotFoundException 
8

물론 예외를 던질 수 있고 실제로는 (생성자에서 삼키는 대신에) 어떻게 할 것인가. 예기치 않은 일이 발생했다는 것을 호출자에게 알리고 싶습니다. 제대로 초기화되지 않은 인스턴스를 반환하고 싶지는 않습니다. 즉, 그것은 일 수 있습니다.은 생성자에서 너무 많은 일을하고 있다는 신호입니다.

+4

왜 방법에 의해 downvote? 설명해 주겠다고? –

+0

+1 그 보상. 다운 voting은 주석 없이는 할 수 없습니다. – BalusC

+0

@BalusC 그게 참 좋을 텐데. –

2

개체를 생성자에서 안전한 상태로 가져 가야하지만 존재하지 않는 파일 (읽기 용)을 열고 싶다고 가정 해 봅시다. 예외가 발생하는 유일한 방법입니다. 그래서 당신이 구현하는 논리에 달려 있습니다.

+0

글쎄, ctor에서 파일을 열어 보지 않으시겠습니까? 사람들이 언제 배울 것인가 ... – EricSchaefer

+3

특히 생성자가 해당 파일에서 작동하도록 의도 된 경우 생성자에서 파일을 열지 않는 이유는 무엇입니까? – Glen

+0

그래, tt 포인트 글렌, 내 개체가 파일을 사용하여 개체를 파일을 사용할 수없는 경우 생성자 – i2ijeya

3

저에게 그것은 효율성의 문제가 아닙니다.

예외 상태에 대응할 수 있고 유효하거나 적어도 사용 가능한 개체를 만드는 경우 생성자 내에서 처리 할 수 ​​있습니다.

그렇지 않으면 개체를 사용할 수없는 경우 예외를 호출자에게 다시 throw합니다. 이 경우 객체를 얻지 못하고 응용 프로그램의 다른 부분에서 오류가 발생할 수있는 사용 불가능한/일관성없는 인스턴스를 계속 사용할 수 없습니다.

+0

@Downvoter - SO FAQ를 읽고 의견을 남겨주세요 –

2

나는 try/catch를 제안하고 catch에서 유용한 오류를 던집니다. 이렇게하면 사용자가 응용 프로그램에 어떤 문제가 있는지 잘 파악할 수 있습니다. 예를 들어, 파일 존재 여부와 올바른 형식의 조건을 확인해야합니다.

1

일반적으로 생성자에서 간단한 논리 만 사용하는 것이 좋습니다 (예 : 인수 값을 사용하여 개인 필드 설정). 그리고 다른 특별한 "어셈블러", "작성자"또는 "공장"으로 개체를 설정하십시오. 같은 것은 get/set 메서드에 관한 것이므로 가능한 한 간단해야합니다.

물론 예외를 throw 할 수 있습니다. 그러나 이것은 좋은 습관이 아닙니다.

+0

생성자는 무엇을해야하는지에 상관없이 객체를 사용 가능하고 일관된 상태로 두어야합니다. 그것이 불가능하다면, 어떤 이유에서 건 그것이 신호를 보내야합니다. 일종의 오류 코드를 반환하면 버그를 묻는 것이며, 다른 선택은 예외를 throw하는 것입니다. –

+0

그래서 뭐? 대부분의 경우 생성자가 실패 할 수있는 작업을 수행해서는 안된다는 의미입니다. –

1

생성자에서 예외를 throw하는 것이 생성자 내부의 오류 조건을 나타내는 우아한 방법이라고 생각합니다. 그렇지 않으면 리소스를 초기화하는 다른 함수를 만들어야하고 객체가 생성 된 후에 해당 함수를 호출해야합니다.

3

가능합니다 (예 : FileOutputStream).

생성자에서 예외를 throw하는 것이 현명하게 수행되어야합니다. 자신을 깨끗하게 정리해야합니다. RAII이 유지되는지 확인하기 위해 생성자에서 예외를 throw하는 경우가 있습니다.

6

생성자를 고려하거나 어떤 방법 으로든 계약을 맺을 것을 고려하십시오. 생성자에 대한 계약은 매우 간단합니다. 즉, (0, 하나 이상의) 매개 변수를 주면 생성 된 객체를 돌려 줄 것입니다. 모범 사례는이 객체가 내부적으로 데이터 구조가 제대로 초기화되고 불변성이 그대로 유지되어야 함을 제안합니다.

어떤 이유로 생성자가이 계약을 유지할 수없는 경우 예외가 발생합니다. 전달 된 매개 변수가 허용되는 경우 (사전 조건 실패) 또는 일부 외부 문제 (파일 시스템 가득 참, 힙 고갈, 네트워크 중단 등)로 인해 발생했을 수 있습니다.

관련 문제