java.util.ArrayList가 왜 널을 추가 할 수 있습니까?


41

java.util.ArrayList추가 할 수 있는지 궁금 합니다 null. 에 추가하고 싶은 경우 nullArrayList있습니까?

프로젝트에서 일부 코드가 추가 되는 버그가 있었고 버그가있는 곳을 찾기가 어려웠 기 때문에이 질문 null을하고 ArrayList있습니다. 분명히 NullPointerException다른 코드가 요소에 액세스하려고 시도 할 때까지는 발생하지 않았습니다. 문제는 null객체 를 추가 한 코드를 찾는 방법이었습니다 . ArrayList요소가 추가 된 코드에서 예외를 던지면 더 쉬웠을 것 입니다.


12
구아바 프로젝트그 주제에 꽤 흥미로운 페이지를 (그들은 허용하지 않습니다 null자신의 컬렉션의 대부분을).
Joachim Sauer

6
나는 여기에 주어진 대답이 그 질문을 잘 덮고 있다고 생각합니다. 아마도 한 가지 언급해야 할 것이 있습니다. JDK에있는 모든 것을 홀리와 완벽한 것으로 취하지 말고 왜 그것이 "완벽한"지 이해하려고 노력하십시오. 이전 버전과의 호환성으로 인해 남아있는 (정직한 IMHO) 실수가 있습니다. Java 제작자조차도 인정합니다. Joshua Bloch의 책을 읽고 특정 Java API에 대한 그의 비판을보십시오. 어쨌든 귀하의 질문은 날씨에 따라 달라집니다. Java로 NPE를 잡는 더 우아한 방법은 없습니다. 대답은 '아니오'입니다.
Shivan Dragon

2
허용되지 않아야하는 이유에 대한 자세한 정보를 제공 할 수 있습니까? 그것이 맛의 문제라면 덜 덜 제한적이어야합니다.
Mare Infinitus

간단한 대답은 null그것이 원하는지 아닌지 Java에서 누락 된 데이터를 나타내는 기본 방법입니다. 사실 많은 사람들이 그것을 좋아하지 않고 함수형 프로그래밍 스타일의 것들에 대한 논쟁으로 만듭니다. 가장 선의적인 답변은 문제의 본질을 포착하지 못하거나 의미가 없습니다.
xji

@JIXiang 당신은 무엇을 지나치게 단순화하고 null있습니다. "실종"은에 대한 몇 가지 잠재적 해석 중 하나 일뿐입니다 null. 다른 유효한 해석은 "알 수 없음", "적용 불가"또는 "초기화되지 않음"일 수 있습니다. 어떤 null표현하면 응용 프로그램에 따라 다릅니다. 파이썬 커뮤니티는 "모호함에 직면하여 추측하려는 유혹을 거부합니다"라고 말할 것입니다. 완벽하게 수행 할 수있는 컨테이너에 null을 유지하는 것을 거부하는 것은 그저 추측 일 것입니다.
riwalk

답변:


34

이 디자인 결정은 대부분 명명에 의해 결정됩니다.

이름 의 ArrayList는 독자에게 유사한 기능 제안 배열을 - 그리고 것은 당연하다 자바 컬렉션 프레임 워크의 디자이너가 API 사용자의 대다수는 배열과 유사한 기능에 의존 할 것으로 예상 할 수 있습니다.

이것은 특히 널 요소의 처리와 관련이 있습니다. 아래에서 작동한다는 것을 알고있는 API 사용자는 정상적으로 작동합니다.

array[0] = null; // NPE won't happen here

매우 놀라게 ArrayList에 대한 유사한 코드가 NPE를 슬로우 있는지 확인하려면 :

arrayList.set(0, null); // NPE => WTF?

위와 같은 추론 은 ArrayList와 일반 배열 사이의 유사성을 제안하는 JCF 자습서 강조점 에서 제시됩니다 .

ArrayList ...는 일정한 시간 위치 액세스를 제공하며 평범한 속도입니다 ...

null을 허용하지 않는 List 구현을 원한다면 NonNullableArrayListAPI 사용자를 혼동하지 않도록 유사 하게 호출하는 것이 좋습니다 .


여기에 제시된 추론을 뒷받침하는 추가 고려 사항 과 함께 아래 의견에 대한 보조 토론이 있습니다.


12
이 설명은 목록 항목 LinkedList 지원 한다는 점 고려하면 설득력이 없습니다 null.
Stephen C

12
그러나 ...하지만 더 간단하고 (IMO) 더 그럴듯한 설명은 null항목 을 허용 하는 것이 많은 경우에 유용하다는 것입니다.
Stephen C

7
ArrayList는 배열을 모방하기 때문에 그렇게 호출되지 않습니다. 배열로 구현 된 목록이기 때문에 그렇게 호출됩니다. TreeMap이 Tree처럼 동작하지 않는 것처럼.
Florian F

11
이 답변, IMO는 명백한 잘못입니다. Java에서는 더 나은 또는 더 나쁜 이유로 (IMO, 나쁨) 널이 초기화되지 않거나 누락 된 값을 나타내는 데 많이 사용되므로 널이 허용됩니다. 가장 많은 표와 "수락"을 어떻게 얻었습니까? 정말 요즘 StackOverflow에 대한 믿음을 잃고 있습니다.
user949300

8
이 답변은 잘못되었습니다. 이것은 목록 구현에서 허용되는 null에 대한 지원되지 않는 추측입니다. 여기입니다 검거 / 허용하지 널 (null)을 허용하는 자바 컬렉션은; 배열과의 유사성과 는 아무런 관련없습니다 .
Andres F.

32

널은 목록의 요소에 유효한 값일 수 있습니다. 목록에 사용자 목록에 대한 선택적 데이터를 나타내는 요소가 포함되어 있고 사용자와 동일한 순서로 저장되어 있다고 가정 해보십시오. 추가 데이터가 채워지면 목록에 추가 데이터가 포함되고 그렇지 않으면 사용자에 해당하는 슬롯이 널이됩니다. (더 나은 예가 있다고 확신하지만 아이디어를 얻습니다)

null을 추가하지 않으려면 null을 추가했을 때 던지는 자신의 래퍼로 배열 목록을 래핑 할 수 있습니다.


2
null이 허용되는 이유의 나쁜 예처럼 보입니다. 목록에서 null 값을 사용하는 것보다 선택적 데이터를 나타내는 더 좋은 방법이 있습니다.
casablanca

@ casablanca 예, 전적으로 동의하지만 훌륭한 예는 아닙니다.
Sam Holder

/ :이 '발견'에 ArrayList를 다음 개발자 널 (null), 다른 후 나쁜 놀라움을 포함하는 나는 좋은 이유를 찾을 수 없습니다
AndreasScheinert

7
@casablanca 동의하지만 Java에서 선택적 데이터를 나타내려면 null을 피해야합니다.
user949300

2
견고한 사용 사례 : 매개 변수를 일부 동적 함수에 목록으로 전달하려고합니다. 각각 다른 매개 변수 집합을 가진 여러 함수가 있으므로 동적으로 크기가 지정된 배열이 필요하며 항상 유효한 함수 인수로 null을 전달할 수 있습니다!
Falco

19

ArrayList의도적으로 null을 허용합니다. 의도적입니다. 로부터 의 javadoc :

"[ArrayList는 크기 조정이 가능한 List 인터페이스의 배열 구현입니다. 모든 선택적 목록 작업을 구현하고 null을 포함한 모든 요소를 ​​허용합니다 ."

"why"에 대한 대답은 ArrayList를 사용하지 않으면 null목록 에 넣어야하는 경우 사용할 수 없다는 것 입니다. 반대로, 값을 추가하기 전에 값을 테스트하거나이를 방지하는 랩퍼를 사용하여 ArrayList에 널이 포함되지 않도록 할 수 있습니다.

ArrayList에 null을 추가하려는 경우가 있습니까?

분명한 null의미가있는 모든 경우 입니다. 예를 들어 목록의 특정 위치에있는 값이 초기화되거나 제공되지 않았 음을 의미 할 수 있습니다.

ArrayList가 요소가 추가되는 코드에서 예외를 throw하면 더 쉬웠을 것입니다.

랩퍼 클래스를 작성하여 해당 동작을 쉽게 구현할 수 있습니다. 그러나 이것은 대부분의 프로그래머 / 응용 프로그램에 필요한 동작이 아닙니다 .


8

ArrayList에 null을 추가하려는 경우가 있습니까?

물론, 사전 할당은 어떻습니까? ArrayList충분한 정보가 없기 때문에 아직 만들 수없는 것들을 원합니다 . 누군가가 무언가를하고 싶어하는 이유를 생각할 수 없다고해서 나쁜 생각이되지는 않습니다. 도대체 무엇이. (이제 누군가가 와서 당신이 대신 모호한 블로그에서 읽은 패턴을 충족시키는 빈 객체를 가져야한다고 말하고 프로그래머는 if진술을 사용하지 않고 프로그램을 실제로 작성할 수 있어야합니다 .

null컨테이너에 s가 없어야 하는 계약이있는 경우 계약을 준수하는 것이 가장 적절하다고 주장하는 것은 귀하에게 달려 있습니다. 아마도 최대 10 줄의 코드를 사용했을 것입니다. Java를 사용하면 이런 종류의 작업을 매우 쉽게 수행 할 수 있습니다. JDK가 당신의 마음을 읽을 수 없습니다.


1
사전 할당 인수는 이미 ensureCapacity(int minCapacity)메서드와 ArrayList(int initialCapacity)생성자를 사용하여 ArrayList에 빌드되었으므로 유효하지 않습니다 .
Philipp

7
@ 필립 그 공간에 어떤 가치가 있을까요?
제임스

명백한 선택은 null사전 할당 된 (그러나 아직 사용되지 않은 ) 항목에 ArrayList; 그러나 우리는 ensureCapacity그렇게 할 수는 있지만 다른 기능을 허용하지는 않습니다 set. 다른 곳에 주어진 이유가 더 강해 보입니다.
David K

@DavidK :에 set의해 반환 될 수있는 임의의 값으로 아이템 이 가능해야한다고 말하는 것이 합리적 get입니다. get공간이 할당되었지만 쓰여지지 않은 항목에 대한 정상적인 시도 가 반환하지 않고 예외를 발생시켜야 null하더라도 여전히 list1.setOrEraseIfNull(index, list2.getOrReturnNull(index))요구하지 않고 허용 할 수있는 한 쌍의 메소드를 갖는 것이 유용 할 것입니다.if (list2.valueSet(index)) list1.set(index, list2.get(index)); else list1.unset(index);
supercat

1
@DavidK : 할당되었지만 아직 작성되지 않은 항목을 읽으려고하면 null이 발생하거나 예외가 발생해야합니다. null을 반환하는 것이 더 쉽습니다.
supercat

4

이것은 여기서 (소프트웨어) 철학적 질문에 가깝습니다.

ArrayList 유틸리티 클래스는 가능한 사용 사례의 광범위한 맥락에서 도움이되도록 설계되었습니다.

null을 유효한 값으로 받아들이는 것이 바람직하지 않다는 숨겨진 주장과는 달리 null 값이 완벽하게 합법적 인 예가 많이 있습니다.

가장 중요한 이유는, 즉 null은 IS do not know프레임 워크 타입을 포함하는 임의의 참조 유형의 등가. 이는 널을보다 유창한 nothing값 으로 대체 할 수 없음을 의미합니다 .

따라서 정수 1, 3, 7을 해당 색인의 배열 목록에 저장한다고 가정 해 보겠습니다. 일부 계산으로 인해 색인 5에서 요소를 가져 오려고하므로 배열이 반환 해야하는 것은 "값이 저장되지 않았습니다"입니다. 이것은 null 또는 NullObject 를 반환하여 달성 할 수 있습니다 . 대부분의 경우 내장 null 값을 반환하는 것으로 충분합니다. null 반환 할 수 있는 메서드를 호출하고 해당 반환 값을 사용하면 null에 대해 반환 된 값을 확인하는 것이 최신 코드에서 매우 일반적입니다.


4

진술

File f = null;

유효하고 유용합니다 (이유를 설명 할 필요가 없다고 생각합니다). 마찬가지로 파일 모음을 갖는 것이 유용하며 그 중 일부는 null 일 수 있습니다.

List<File> files = new ArrayList<File>();
// use my collection of files
// ....
// not using this one anymore:
files.set(3, null);

null 객체를 포함 할 수있는 컬렉션의 유용성은 null 일 수있는 객체의 유용성에서 직접 진행됩니다. 정말 간단합니다.


2

제한적이되는 것보다 모든 것을 받아들이는 것이 더 쉬우 며 사실 후에 디자인을 열어보십시오.

예를 들어 oracle / sun이 NonNullableArrayList 만 제공했지만 목록에 Null을 추가 할 수있게하려면 어떻게해야합니까? 어떻게 하시겠습니까? 완전히 다른 객체를 만들어야 할 수도 있습니다. NonNullableArrayList를 확장하여 사용할 수 없습니다. 대신 모든 것을 취하는 ArrayList가 있으면 쉽게 확장하고 null 값을 허용하지 않는 add를 재정의 할 수 있습니다.


2
동의하지 않습니다. 잘못된 기능이 널리 사용되면 너무 많이 허용하면 수정하기가 더 어렵습니다. 언어 디자이너가 이후 단계에서 null을 허용하면 기존 프로그램이 중단되지 않지만 그 반대는 아닙니다.
Andres F.

2
하지만 동의합니다. 기능을 극대화하는 것입니다. 필요하지 않은 경우에도 널을 허용하는 목록을 사용할 수 있습니다. 널이 필요한 경우 널을 거부하는 목록을 사용할 수 없습니다.
Florian F

-1

널의 유용성?

리스트리스트를 사용 하여 다른 위치 로 2D 실제 플레이트를 모델링 할 때 매우 그렇습니다 . 채워진 위치는 단순한 int 또는 String을 나타내지 않지만 복잡한 객체로 표시되는 반면 해당 위치의 절반은 임의의 좌표로 비어있을 수 있습니다 . 위치 정보를 유지하려면 list.get (x) .get (y)가 되도록 빈 자리를 null로 채워야합니다.불쾌한 놀라움으로 이어지지 않습니다. null 예외를 방지하기 위해 null (매우 인기있는)을 확인하거나 Optional (이 경우 편리함)을 사용할 수 있습니다. 대안은 빈 지점을 "정크"물체로 채우면 모든 종류의 혼란이 발생할 수 있습니다. null 검사가 실패하거나 어딘가 잊혀지면 Java에서 알려줍니다. 반면, 제대로 확인되지 않은 "정크"자리 표시 자 개체는 눈에 띄지 않게 전달 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.