생성자 내부에서 파일 객체를 초기화해야하고 예외를 처리하려면 throws
을 사용하는 것이 효율적입니까? 아니면 try
/catch
을 사용해야합니까?생성자에서 throw를 사용할 수 있습니까?
답변
생성자에서 예외를 발생시키는 것이 좋습니다. 나는 Java 라이브러리 클래스 중 일부가 그렇게한다는 것을 안다. (한 가지 예를 들면 URI). 알 수 없거나 유효하지 않은 상태의 객체를 반환하는 것보다 예외를 throw하는 것이 더 좋습니다.
'URL' 클래스는 나쁜 코드 이외의 다른 좋은 예가 아닙니다. 예를 들어, 'equals' 메서드는 인터넷에 연결되어 있는지 여부에 따라 다른 값을 반환합니다. (그냥 편이 아니라면 답이 좋습니다) – abyx
@abyx : 이제 언급 했으니, 전적으로 동의합니다 URL에 대해. URI 대신 예제를 사용하여 내 대답을 변경했습니다. 감사. –
URI/URL에 주목해야 할 것이 하나 있는데, 나쁜 입력을 주면 예외가 던져진다. (파일을 열거 나 DNS 조회를 수행하는 것과 같이) 커버 아래에서 뭔가가 일어나기 때문에가 아니라. –
당신이 생각하는 생성자에서 초기화되는 것에 관심이 있다면 'throws'와 함께 갈 것입니다.
예외를 숨기면 나중에 문제가 발생할 수 있습니다.
해당 코드 작성 표준이 throwed in 건설자? – i2ijeya
아니요, 그렇지 않습니다. ctor에서 파일을 열지 마십시오. ctor는 내부 상태의 기본 초기화를위한 것입니다. 파일/네트워크/데이터베이스 작업을해야하는 경우 추가 open()/init()/whatever() 메소드에서 수행하십시오. – EricSchaefer
@Eric, 초기화 메소드는 코드 냄새입니다. 객체를 생성 할 때마다 init을 호출해야한다면, init 로직을 생성자에 넣으십시오. 객체 사용자가 init을 호출하여 시스템에 버그를 삽입하는 것을 잊어 버릴 수밖에 없습니다. – Glen
일반적으로 생성자에서 많은 작업을 수행하는 것은 좋지 않습니다. 여러 언어로 작성 중에 예외에 대해 수행 할 수있는 작업이 제한 될 수 있습니다.
다른 언어의 제약으로 인해 절대로 Java로해서는 안된다는 말입니까? 이것이 당신의 요점이라면, 나는 동의하지 않는다. –
@Pascal : ** Java **에서 당신을 멈추게하는 것은 아무 것도 없습니다. 원한다면 계속하십시오. 그러나 다른 많은 유용한 언어가 그러한 연습을 방해하기 때문에 다른 언어 (예 : C++)를 사용할 때 명심해야 할 "규칙"이 하나 더 있습니다. ** 당신이 ** 오직 ** 자바 프로젝트에만 도전한다면, 내 의견을 무시해도 좋습니다. – jldupont
"무거워 짐"을 정의하십시오. 나는 이것이 "너무 많이하지 마라"라고 말하는 것 같아요. 얼마나 많은 것을 말하지 않고 말입니다. –
물론 자바에서는 실제로 많이 사용됩니다. 예를 들어,
public FileInputStream(String name)
throws FileNotFoundException
물론 예외를 던질 수 있고 실제로는 (생성자에서 삼키는 대신에) 어떻게 할 것인가. 예기치 않은 일이 발생했다는 것을 호출자에게 알리고 싶습니다. 제대로 초기화되지 않은 인스턴스를 반환하고 싶지는 않습니다. 즉, 그것은 일 수 있습니다.은 생성자에서 너무 많은 일을하고 있다는 신호입니다.
왜 방법에 의해 downvote? 설명해 주겠다고? –
+1 그 보상. 다운 voting은 주석 없이는 할 수 없습니다. – BalusC
@BalusC 그게 참 좋을 텐데. –
개체를 생성자에서 안전한 상태로 가져 가야하지만 존재하지 않는 파일 (읽기 용)을 열고 싶다고 가정 해 봅시다. 예외가 발생하는 유일한 방법입니다. 그래서 당신이 구현하는 논리에 달려 있습니다.
글쎄, ctor에서 파일을 열어 보지 않으시겠습니까? 사람들이 언제 배울 것인가 ... – EricSchaefer
특히 생성자가 해당 파일에서 작동하도록 의도 된 경우 생성자에서 파일을 열지 않는 이유는 무엇입니까? – Glen
그래, tt 포인트 글렌, 내 개체가 파일을 사용하여 개체를 파일을 사용할 수없는 경우 생성자 – i2ijeya
저에게 그것은 효율성의 문제가 아닙니다.
예외 상태에 대응할 수 있고 유효하거나 적어도 사용 가능한 개체를 만드는 경우 생성자 내에서 처리 할 수 있습니다.
그렇지 않으면 개체를 사용할 수없는 경우 예외를 호출자에게 다시 throw합니다. 이 경우 객체를 얻지 못하고 응용 프로그램의 다른 부분에서 오류가 발생할 수있는 사용 불가능한/일관성없는 인스턴스를 계속 사용할 수 없습니다.
@Downvoter - SO FAQ를 읽고 의견을 남겨주세요 –
나는 try/catch를 제안하고 catch에서 유용한 오류를 던집니다. 이렇게하면 사용자가 응용 프로그램에 어떤 문제가 있는지 잘 파악할 수 있습니다. 예를 들어, 파일 존재 여부와 올바른 형식의 조건을 확인해야합니다.
일반적으로 생성자에서 간단한 논리 만 사용하는 것이 좋습니다 (예 : 인수 값을 사용하여 개인 필드 설정). 그리고 다른 특별한 "어셈블러", "작성자"또는 "공장"으로 개체를 설정하십시오. 같은 것은 get/set 메서드에 관한 것이므로 가능한 한 간단해야합니다.
물론 예외를 throw 할 수 있습니다. 그러나 이것은 좋은 습관이 아닙니다.
생성자는 무엇을해야하는지에 상관없이 객체를 사용 가능하고 일관된 상태로 두어야합니다. 그것이 불가능하다면, 어떤 이유에서 건 그것이 신호를 보내야합니다. 일종의 오류 코드를 반환하면 버그를 묻는 것이며, 다른 선택은 예외를 throw하는 것입니다. –
그래서 뭐? 대부분의 경우 생성자가 실패 할 수있는 작업을 수행해서는 안된다는 의미입니다. –
생성자에서 예외를 throw하는 것이 생성자 내부의 오류 조건을 나타내는 우아한 방법이라고 생각합니다. 그렇지 않으면 리소스를 초기화하는 다른 함수를 만들어야하고 객체가 생성 된 후에 해당 함수를 호출해야합니다.
가능합니다 (예 : FileOutputStream
).
생성자에서 예외를 throw하는 것이 현명하게 수행되어야합니다. 자신을 깨끗하게 정리해야합니다. RAII이 유지되는지 확인하기 위해 생성자에서 예외를 throw하는 경우가 있습니다.
생성자를 고려하거나 어떤 방법 으로든 계약을 맺을 것을 고려하십시오. 생성자에 대한 계약은 매우 간단합니다. 즉, (0, 하나 이상의) 매개 변수를 주면 생성 된 객체를 돌려 줄 것입니다. 모범 사례는이 객체가 내부적으로 데이터 구조가 제대로 초기화되고 불변성이 그대로 유지되어야 함을 제안합니다.
어떤 이유로 생성자가이 계약을 유지할 수없는 경우 예외가 발생합니다. 전달 된 매개 변수가 허용되는 경우 (사전 조건 실패) 또는 일부 외부 문제 (파일 시스템 가득 참, 힙 고갈, 네트워크 중단 등)로 인해 발생했을 수 있습니다.
- 1. 클래스 생성자에서 매개 변수를 사용할 수 있습니까?
- 2. 기본 생성자에서 하드 코딩 된 값을 사용할 수 있습니까?
- 3. PHP의 생성자에서 무엇을 추가 할 수 있습니까?
- 4. 생성자에서 객체 생성을 중단 할 수 있습니까?
- 5. 생성자에서 Java 객체를 서브 클래스화할 수 있습니까?
- 6. throw를 추가하기 때문에 C++ 링커가 작동하지 않습니다.
- 7. ThreadAbortException을 잡을 때 숨겨진 Throw를 어떻게 처리합니까?
- 8. 어떻게 C++ 생성자에서 다형성 동작을 얻을 수 있습니까?
- 9. 을 사용할 수 있습니까?
- 10. 타이머를 사용할 수 있습니까?
- 11. alcheMo를 사용할 수 있습니까?
- 12. jquery를 사용할 수 있습니까?
- 13. TestContext.Properties를 사용할 수 있습니까?
- 14. 을 사용할 수 있습니까?
- 15. pushState를 사용할 수 있습니까?
- 16. killProcess를 사용할 수 있습니까?
- 17. Auto_publish를 사용할 수 있습니까?
- 18. Java : 생성자에서 예외가 발생했습니다. 내 개체를 여전히 만들 수 있습니까?
- 19. 개체가 생성자에서 정적 또는 동적으로 할당되었는지 어떻게 알 수 있습니까?
- 20. 어떻게 펄 생성자에서 빈 배열을 정의 할 수 있습니까?
- 21. C#, 생성자에서 사전 초기 코드를 이동할 수 있습니까?
- 22. 하위 클래스의 생성자에서 추상 클래스의 생성자에 대리자를 전달할 수 있습니까?
- 23. 외부 클래스의 생성자에서 내부 클래스의 객체를 만들 수 있습니까?
- 24. Perl의 해시 생성자에서 익명 서브 루틴을 정의 할 수 있습니까?
- 25. 생성자에서 super()보다 먼저 계산을 수행 할 수 있습니까?
- 26. C# : LINQ를 사용하여 클래스 생성자에서 개체를 초기화 할 수 있습니까?
- 27. 일반 메서드로 다른 생성자에서 생성자를 호출 할 수 있습니까?
- 28. symfony의 admin 생성자에서 peer_method
- 29. PHP : 생성자에서 $ this 사용하기
- 30. C++ 객체 생성자에서 OpenMP 사용
관련 항목 : http://stackoverflow.com/questions/1183531/how-much-work-should-the-constructor-for-an-html-parsing-class-do –