Boolean의 null 값은 언제 사용해야합니까?


159

자바 boolean의 값을 허용 true하고 false부울 수 있지만 true, false하고 null. booleans를 Booleans 로 변환하기 시작했습니다 . 다음과 같은 테스트에서 충돌이 발생할 수 있습니다.

Boolean set = null;
...
if (set) ...

시험하는 동안

if (set != null && set) ...

생각하고 오류가 발생하기 쉬운 것 같습니다.

Booleans를 null 값과 함께 사용하는 것이 유용한 경우는 언제 입니까? 그렇지 않다면, 포장 된 물체의 주요 장점은 무엇입니까?

업데이트 : 나는 내 자신의 답변으로 그중 일부를 요약 한 귀중한 답변이 많이있었습니다. 나는 자바에서 중간체이기 때문에 내가 찾은 것을 보여 주려고 노력했다. 질문은 "부정확하게 표현되었습니다"(부울은 "널값을 가질 수 없음")지만 다른 사람들이 동일한 오해를 가지고있는 경우에 대비하여 남겨 두었습니다.


7
때로는 초기화되지 않은 상태를 원하고 Boolean변수를 설정 null하는 것이 좋습니다.
nhahtdh 2016 년

2
"항상"은 감히 확신 할 수없는 약간 강하지 만, null실제로 3 번째 상태로 사용되는지 테스트를 기대합니다 .
nhahtdh 2016 년

6
부울을 부울로 변환 할 이유가 있습니까? 기본 유형을 고수하고 그렇게 해야하는 이유가있는 경우에만 래핑합니다 (예 : 변수를 참조로 전달 해야하는 경우).
jpe

7
: 당신이 체크 아웃 할 수 있습니다 thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
biziclop

6
는 "널 (null) 값 같은 것은 없다 에서 부울". A Boolean는 객체이고 a boolean는 "스칼라"입니다. Boolean참조가 null로 설정된 경우 해당 Boolean객체가 존재하지 않음 을 의미 합니다. 존재하지 않는 어떤 것도 안에 넣을 수 없습니다.
핫 릭

답변:


244

사용 boolean하기보다는 Boolean당신이 할 수있는 모든 시간입니다. 이것은 많은 것을 피하고 NullPointerException코드를 더 강력하게 만듭니다.

Boolean 예를 들어 유용합니다

  • 부울을 컬렉션에 저장하기 (List, Map 등)
  • 예를 들어 데이터베이스의 널 입력 가능 부울 열에서 오는 널 입력 가능 부울을 나타냅니다. 이 값에서 null 값은 "true인지 false인지 모른다"를 의미 할 수 있습니다.
  • 메소드가 Object를 인수로 필요로 할 때마다 부울 값을 전달해야합니다. 예를 들면, 반사 또는 방법을 같이 사용하는 경우 MessageFormat.format().

35
데이터베이스의 null 값은 "FileNotFound"를
Karl Johan

31
두 번째 글 머리표는이 질문에 대한 정답의 핵심입니다.
Niels Brinch 2016 년

3
내가 가진 부울의 또 다른 용도는 일반 클래스를 확장 할 때 일반 유형 매개 변수로 사용됩니다. 포인트 3과 밀접한 관련이 있습니다.
Alex

6
"우주가 모른다"이외의 의미로 null의 개념을 오버로드하면 3 (또는 그 이상)의 값을 가진 열거 형을 사용하는 것보다 약합니다. 코드를 매개 변수를 메소드로 전달하는 코드를보다 명확하게 만듭니다.
bluevector

16
또는 # 4 : Boolean isSchrodinger‎CatAlive = null;(죄송합니다. 저항 할 수 없었습니다).
Matthieu

58

Boolean그 의미가 모호하고 모호 하기 때문에 거의 사용하지 않습니다 . 기본적으로 3 가지 상태 로직이 있습니다 : true, false 또는 unknown. 예를 들어 사용자에게 두 값 중 하나를 선택할 수 있고 사용자가 전혀 대답하지 않았으며 해당 정보를 알고 싶을 때 (널 (NULL) 입력 가능 데이터베이스 열) 생각할 때 유용합니다.

나는 변환 할 이유 볼 booleanBoolean는 추가 메모리 오버 헤드, NPE 가능성 덜 입력을 소개하면서. 일반적으로 나는 어색한 것을 사용 BooleanUtils.isTrue()하여 내 인생을 조금 더 쉽게 Boolean만듭니다.

존재하는 유일한 이유 BooleanBoolean유형의 콜렉션을 보유 할 수있는 능력입니다 (제네릭은 boolean물론 다른 모든 기본 요소도 허용하지 않습니다 ).


1
그러나 외부 라이브러리 (Apache commons)입니다.
nhahtdh 2016 년

4
다중 값 논리의 경우 열거 형을 사용하는 것이 좋습니다. 따라서 데이터 구조에 사용하기 위해 (자동) 복싱 변수에 대해 부울을 남겨 두어야합니다.
jpe

39
부울을 사용할 때 널 포인터 예외를 피하기위한 편리한 테스트는 Boolean.TRUE.equals(myBooleanObject)또는 Boolean.FALSE.equals(myBooleanObject)입니다.
Christopher Peisert

10
부울 객체는이 상태가 - truefalse. null없는 개체의 상태가 아니라 객체 참조 상태.
핫 릭

2
isTrue()유틸리티 기능의 역사에서 가장 끔찍한 괴물처럼 들리는 "누군가 부울을 평가할 수 있습니다 ... 방법을 만들어 보자 ..."와 같은 아파치 공통점을 남겨 두십시오 . 그러나 어쨌든 유용합니다 ... 여기서 가장 큰 무게입니다.
corsiKa

33

와우, 지구상에서 무엇? 그것은 단지 나입니까? 아니면이 모든 대답이 틀리거나 적어도 오도입니까?

부울 클래스는 부울 프리미티브 유형의 래퍼입니다. 이 랩퍼를 사용하면 오브젝트 또는 제네릭을 허용하는 메소드에서 부울을 전달할 수 있습니다. 즉 벡터.

부울 객체는 절대 null 값을 가질 수 없습니다. 귀하의 경우 참조 부울에가 null이며, 그것은 단순히 부울 생성하지 않았 음을 의미합니다.

이 유용한 것을 찾을 수 있습니다 : http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Boolean.java

널 부울 참조는 다른 널 참조와 유사한 논리를 트리거하는 데만 사용해야합니다. 세 가지 상태 논리에 사용하는 것은 어색합니다.

편집 : 통지, 그것은 Boolean a = true;오해의 소지가 있습니다. 이것은 자동으로 가까운 것을 Boolean a = new Boolean(true); 참조하십시오 : http://en.wikipedia.org/wiki/Boxing_%28computer_science%29#Autoboxing

아마도 이것은 많은 혼란의 근원입니다.

EDIT2 : 아래의 의견을 읽으십시오. 누구든지 이것을 통합하기 위해 내 대답을 재구성하는 방법에 대한 아이디어가 있다면 그렇게하십시오.


2
"부울은 절대 null 값을 가질 수 없습니다"라는 문장을 이해하지 못합니다. 부울 ( Boolean a = true;)을 만든 다음 a를 null ( a = null;) 로 설정할 수 있습니다 . 우아하거나 현명하지는 않지만 가능합니다.
peter.murray.rust

7
당신이 할 때 Boolean a; a는 부울 객체에 대한 포인터입니다. a = null;부울을 널로 설정하지 않은 경우 참조를 널로 설정 한 것입니다. 수행 Boolean a = null; a.booleanValue();이 경우 도 만든 적이 Boolean 객체를 따라서 그것은 NullPointerException이 던질거야. 추가 지시가 필요한 경우 알려주십시오.
user606723

또한 수행 할 때 Boolean a = true;실제로 Boolean a = new Boolean(true);성능상의 이유로 완전히 정확하지는 않지만 실제로 부울은 여전히 ​​객체라는 것을 알아야합니다.
user606723

7
@missingno, 모든 객체를 다루는 모든 코드는 이것을 처리해야합니다. 객체 참조는 null이거나 그렇지 않을 수 있습니다. 이것은 특별한 경우가 아니며 특별한 고려가 필요하지 않습니다.
user606723

3
내 요점 @missingno를 놓치고 있습니다. null 참조 값을 고려해야한다는 데 동의합니다. 나는 결코 그런 주장에 반대하지 않았습니다. 그러나 모든 객체 참조 를 위해서는이 작업을 수행해야합니다 . 널 부울 참조는 특별한 경우가 아닙니다. 따라서 null 부울 참조 값은 특별한 고려가 필요하지 않습니다.
user606723

24

세 가지 빠른 이유가 있습니다.

  • 데이터베이스 부울 값을 나타내려면 true, false또는null
  • xsd:boolean선언 된 XML 스키마의 값 을 나타 내기 위해xsd:nillable="true"
  • 일반 유형을 사용할 List<Boolean>수 있습니다.-사용할 수 없습니다List<boolean>

booleanOracle에서는 일반적 char(1) null으로 'T'및 'F'값과 함께 사용하기 때문에 " "(마인드 스타일링)이 아닌 "부울"을 명시 적으로 작성했습니다 . (예를 들어, Hibernate 타입 어댑터) 그 수도는 널 (null) : 수 있도록
그르 Grzybek

2
부울에 null을 허용하지 않는 데이터베이스는 무엇입니까? 열을 널 입력 가능으로 설정하면 데이터 유형이 더 이상 중요하지 않습니다.
Michal B.

@MichalB. 사이베이스 (및 SQL Server) 비트 타입 infocenter.sybase.com/help/index.jsp?topic=/...
MMMMMM

@Mark-아니요, SQL Server는 nullable 비트를 허용합니다.- msdn.microsoft.com
David M

11

자신의 질문에 대한 답변 : 답변에서 많은 것을 배웠으므로 내 질문에 대답하는 것이 도움이 될 것이라고 생각했습니다. 이 답변은 나와 같은 문제를 완전히 이해하지 못하는 사람들을 돕기위한 것입니다. 내가 잘못된 언어를 사용하면 나를 수정하십시오.

  • 널 "값"은 값이 아니며 기본적으로 trueand와 다릅니다 false. 객체에 대한 포인터가 없습니다. 따라서 부울이 3 값이라고 생각하는 것은 근본적으로 잘못되었습니다
  • 부울 구문은 약식이며 참조가 객체를 가리키는 사실을 숨 깁니다.

    Boolean a = true;

true객체 라는 사실을 숨 깁니다 . 다른 동등한 과제는 다음과 같습니다.

Boolean a = Boolean.TRUE;

또는

Boolean a = new Boolean(true);
  • 약식 구문

    if (a) ...

는 대부분의 다른 할당과 다르며 a가 객체 참조이거나 기본 일 수 있다는 사실을 숨 깁니다. 물체 인 경우 nullNPE를 피하기 위해 테스트해야합니다 . 나에게 평등 테스트가 있으면 이것을 기억하는 것이 심리적으로 쉽습니다.

if (a == true) ...

여기서 null을 테스트하라는 메시지가 표시 될 수 있습니다. 따라서 단축 된 형태는 a원시적 일 때만 안전 합니다.

나 자신을 위해 지금 권장 사항이 있습니다.

  • 3 값 논리에는 null을 사용하지 마십시오. 참과 거짓 만 사용하십시오.
  • 절대로 Boolean메소드에서 리턴하지 마십시오 null. 만 반환 boolean합니다.
  • Boolean컨테이너의 요소를 감싸거나 객체가 필요한 메소드에 대한 인수 에만 래핑

5
"new Boolean (whatever)"을 사용하지 마십시오. 힙에서 새 부울을 인스턴스화합니다. 그러나 부울은 변경할 수 없습니다. "Boolean.valueOf (whatever)"를 사용하면 무엇이든지에 따라 Boolean.TRUE 또는 Boolean.False를 가리키는 참조가 생성됩니다.
simbo1905

1
Java (12 년 후 IMHO)와 관련한 많은 문제 중 하나는 이전 언어와 마찬가지로 null 값에 대한 접근 방식의 일관성이 없다는 것입니다. 스칼라를 살펴보면 null이거나 값을 가질 수있는 유형이 지정된 옵션 개념이 있습니다 (하위 클래스 없음 또는 일부). 그런 다음 myOption.getOrElse (defaultValue)를 호출 할 수 있습니다. 이 기능에 대해 복잡한 것은 scala-lang.org/api/current/scala/Option.html을 참조하십시오 . 그러나 새로운 JVM 언어에 내장되어 있으므로 많은 라이브러리가이를 사용합니다. 이는 규모 "수정"을 Java의 "지난 세기"문제의 일부로 만들지 만 여전히 JRE에서 실행되는 클래스 파일로 컴파일됩니다.
simbo1905

10

프리미티브의 래퍼 클래스는 객체가 필요한 곳에서 사용할 수 있으며 컬렉션은 좋은 샘플입니다.

당신이 어떤 이유로 저장소의 순서가 필요 상상 boolean에서을 ArrayList,이 권투하여 수행 할 수 있습니다 boolean에서 Boolean.

여기에 대한 몇 마디가 있습니다

설명서에서 :

Java 프로그래머가 알고 있듯이 int (또는 다른 기본 값)를 컬렉션에 넣을 수는 없습니다. 콜렉션은 오브젝트 참조 만 보유 할 수 있으므로 기본 값을 적절한 랩퍼 클래스 (int의 경우 Integer)로 상자에 넣어야합니다. 컬렉션에서 개체를 가져 오면 삽입 한 정수를 얻게됩니다. int가 필요한 경우 intValue 메소드를 사용하여 Integer를 개봉해야합니다. 이 모든 복싱 및 언 박싱은 고통스럽고 코드를 복잡하게 만듭니다. 오토 박싱 및 언 박싱 기능은 프로세스를 자동화하여 고통과 혼란을 제거합니다.

http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html


3

Boolean래퍼는 값이 trueand과 떨어져 있는지 여부를 원할 때 유용합니다 false. 다음과 같은 세 가지 상태가 있습니다.

  • 진실
  • 그릇된
  • 정의되지 않은 null

반면 boolean에 두 가지 상태 만 있습니다.

  • 진실
  • 그릇된

상기 차이는 목록에 유용한 것 Boolean가질 수있는 값 True, False또는 Null.


아니요, null 상태가 아니므로 참조입니다.
Matsemann 2016 년

내가 의미 한 것은 Bolean을 정의 된 True / False 및 Not Defined에 사용할 수 있습니다.
Ramesh PVK

3

어떤 경우에는 이미 값을 설정했는지 여부를 지정하는 부울 필드를 구별하는 메커니즘이 있어야한다고 가정합니다.


1

부울의 주요 목적은 널값입니다. Null 값은 해당 속성이 정의되어 있지 않습니다 ( 예 : 데이터베이스 Null 허용 열 사용).

모든 기본 요소를 기본 부울에서 래퍼 부울로 변환해야하는 경우 다음을 사용하여 이전 코드를 지원할 수 있습니다.

Boolean set = Boolean.FALSE; //set to default value primitive value (false)
...
if (set) ...

6
'주된 목적은 null 값입니다.' 아니요, 부울의 주요 목적은 부울에 대한 참조를 객체로 전달하는 것입니다.
user606723

@ user606723은 동의하는 동안 데이터베이스 케이스를 언급하고 있다고 동의했습니다.
JMelnik

1

부울 래퍼에는 ** null ** 값이 많이 사용됩니다! :)

예를 들어, 사용자가 사이트에서 뉴스 레터를 원하는지 또는 원하지 않는지를 나타내는 "뉴스 레터"라는 필드의 양식이있을 수 있습니다. 사용자가이 필드에서 값을 선택하지 않으면 해당 상황에 대한 기본 동작을 구현할 수 있습니다 (보내기? 전송하지 않습니까? 다시 질문? 등). 분명히 설정되지 않거나 (또는 ​​선택하지 않거나 ** null **) true 또는 false와 같지 않습니다.

그러나 "설정되지 않음"이 모델에 적용되지 않으면 부울 프리미티브를 변경하지 마십시오.


1

부울 요소의 엄격한 정의에는 두 개의 값만 있습니다. 완벽한 세상에서 그것은 사실입니다. 실제 환경에서는 요소가 누락되었거나 알 수 없습니다. 일반적으로 여기에는 사용자 입력이 포함됩니다. 화면 기반 시스템에서는 편집에 의해 강제 될 수 있습니다. 데이터베이스 또는 XML 입력을 사용하는 배치 환경에서 요소가 쉽게 누락 될 수 있습니다.

따라서 우리가 살고있는 완벽하지 않은 세계에서 부울 객체는 누락되거나 알 수없는 상태를 null로 나타낼 수 있다는 점에서 뛰어납니다. 결국 컴퓨터는 실제 상태를 모델링하고 가능한 모든 상태를 설명하고 예외를 처리해야합니다.

필자의 경우 입력 XML에 때로는 요소가 누락되어 부울에 값을 할당하고 부울에 할당 한 다음 true 또는 false 테스트를 사용하기 전에 null을 확인하기 때문에 부울 객체가 완벽한 대답이었습니다. .

그냥 내 2 센트.


1

위의 모든 좋은 답변을 위해 Java 서블릿 HttpSession클래스 에서 구체적인 예를 들겠습니다 . 이 예가 아직도 어떤 질문을 명확하게하는 데 도움이되기를 바랍니다.

세션 값을 저장하고 검색해야하는 경우 setAttribute(String, Object) 및 getAttribute(String, Object) 방법을 사용합니다. 따라서 부울 값의 경우 http 세션에 부울 클래스를 저장하려면 부울 클래스를 사용해야합니다.

HttpSession sess = request.getSession(false);
Boolean isAdmin = (Boolean) sess.getAttribute("admin");
if (! isAdmin) ...

NullPointerException속성 값이 설정되지 않은 경우 마지막 행은 원인이 됩니다. (이것이 나를이 포스트로 인도 한 이유이다). 따라서 3 가지 논리 상태는 사용 여부에 관계없이 유지됩니다.


0

가장 좋은 방법은 부울을 완전히 피하는 것입니다. 모든 부울은 코드의 다른 곳에 조건문이 있음을 암시하므로 ( http://www.antiifcampaign.com/ 및이 질문 : if 문없이 알고리즘을 작성할 수 있습니까? ? ).

그러나 실용적으로 때때로 부울을 사용해야하지만, 이미 스스로 알았 듯이 부울을 처리하는 것은 오류가 발생하기 쉽고 번거 롭습니다. 따라서 가능한 한 부울을 사용하는 것이 좋습니다. 이 예외는 nullable 부울 열이있는 레거시 데이터베이스 일 수 있지만 매핑에서도 숨기려고합니다.


부울을 다루는 것은 다른 객체를 다루는 것처럼 오류가 발생하기 쉽습니다. BTW, 링크는 일반적인 용도가 아닌 유형 검사를위한 IF의 확산에 대한 것입니다. 그리고 이것은 수정이 더 어려워지기 때문에 "위험한"것입니다. 따라서 IF 자체에는 아무런 문제가 없습니다.
Mister Smith

질문에 대한 답변이 아닙니다.
Matsemann 2016 년

@MisterSmith Imho 부울 플래그는 종종 유형 검사 변수로 잘못 사용되므로 링크도 여기에 적용 할 수 있습니다. 부울이 특정 상황에서 올바른 도구인지 여부를 생각해야한다는 힌트 일뿐입니다. "부울을 완전히 피하십시오"라는 말은 물론 매우 급진적이고 실제로 불가능하기 때문에 두 번째 단락을 추가했습니다. 또한 "오류가 발생하기 쉬우면서 더 번거로운 작업"을 추가하여 내용을 명확하게했습니다.
롤랜드 슈나이더

0

부울은 세 가지 상태가 필요할 때 매우 유용합니다. 소프트웨어 테스트에서 테스트가 통과되면 true를 전송하고, 실패하면 false를 전송하고 테스트 케이스가 중단 된 경우 테스트 케이스가 실행되지 않음을 나타내는 null을 보냅니다.


2
열거 형이 가장 적합하지 않습니까? 클라이언트에 대해 예기치 않은 NullPointerExceptions이 발생할 가능성이있는 것과 달리 열거 형은 "상태"를 명시 적으로 정의합니다.
Kartik Chugh

상태 머신에서는 항상 부울 대신 열거 형을 선호합니다. 새로운 네 번째 주가 비즈니스 요구 사항에 언제 도착하는지 알 수 없습니다.
AnupamChugh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.