무엇입니까 null
?
가 null
아무것도의 인스턴스는?
어떤 세트에 null
속합니까?
메모리에 어떻게 표현됩니까?
무엇입니까 null
?
가 null
아무것도의 인스턴스는?
어떤 세트에 null
속합니까?
메모리에 어떻게 표현됩니까?
답변:
null은 무엇인가의 인스턴스입니까?
아니, 형이없는 null
됩니다 instanceof
.
instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
런타임시,
instanceof
연산자 의 결과true
는 RelationalExpression 의 값 이 아니고 참조 를 a를 올리지 않고 ReferenceTypenull
으로 캐스트 할 수있는 경우 입니다. 그렇지 않으면 결과는 입니다.ClassCastException
false
이 방법이 모든 유형 E
과 R
어떤을위한, E o
, o == null
, o instanceof R
항상 false
.
'null'은 어떤 세트에 속합니까?
이름이없는 특별한 null 유형 인 expression 유형
null
도 있습니다. 때문에 널 유형 이름이없는,의 변수를 선언하는 것은 불가능 널 받는 형식이나 주조에 널 유형입니다.null
레퍼런스의 표현의 유일하게 가능한 값 널 타입.null
참조는 항상 참조 형식으로 캐스팅 할 수 있습니다. 실제로 프로그래머는 널 유형을 무시하고null
참조 유형일 수있는 특수 리터럴 인 것처럼 가장 할 수 있습니다.
널이란 무엇입니까?
위의 JLS 인용문에서 알 수 있듯이 실제로는 단순히 "모든 참조 유형이 될 수있는 특수 리터럴"인 것처럼 가장 할 수 있습니다.
Java에서는 null == null
(다른 언어에서는 항상 그런 것은 아닙니다). 계약에 따라 다음과 같은 특수 속성도 있습니다 java.lang.Object
.
public boolean equals(Object obj)
임의의 비를 들어
null
기준값x
,x.equals(null)
해야한다return false
.
모든 참조 유형에 대한 기본값 이기도합니다 (변수가있는 변수의 경우).
- 각 클래스 변수, 인스턴스 변수 또는 배열 구성 요소 는 작성 될 때 기본값으로 초기화됩니다 .
- 모든 참조 유형의 기본값은
null
입니다.
이것이 사용되는 방법은 다양합니다. 이 필드를 사용하여 필드의 초기 초기화 ( lazy initialize ) 필드 를 활성화 할 수 있습니다 . 필드는 null
실제로 사용될 때까지 초기 값을 가지며 "실제"값 (계산 비용이 많이들 수 있음)으로 대체됩니다.
다른 용도도 있습니다. 실제 사례를 보자 java.lang.System
.
public static Console console()
결과 : 시스템 콘솔 (있는 경우), 그렇지 않은 경우
null
.
이것은 매우 일반적인 사용 패턴 null
입니다. 객체가 존재하지 않음을 나타내는 데 사용됩니다.
다음은 또 다른 사용법 예입니다 java.io.BufferedReader
.
public String readLine() throws IOException
리턴 :
String
행의 내용을 포함하고 행 종료 문자를 포함하지 않거나null
스트림의 끝에 도달 한 경우
그래서 여기에, readLine()
반환 instanceof String
은 마지막으로 반환 될 때까지, 각 라인 null
의 끝을 의미 할 수 있습니다. 이를 통해 다음과 같이 각 줄을 처리 할 수 있습니다.
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
종료 조건이 readLine()
returning에 의존하지 않도록 API를 디자인 할 수 null
있지만이 디자인은 간결하게 만드는 이점이 있음을 알 수 있습니다. 빈 줄 때문에 빈 줄에는 문제가 없습니다 "" != null
.
이번에는 java.util.Map<K,V>
다음 에서 또 다른 예를 보자 .
V get(Object key)
지정된 키가 맵핑 된 값을 리턴하거나이
null
맵에 키에 대한 맵핑이없는 경우 값을 리턴합니다 .이 맵이
null
값을 허용하는 경우 , 리턴 값이null
반드시 맵에 키에 대한 맵핑이 없음을 나타내는 것은 아닙니다. 지도가 키를에 명시 적으로 매핑 할 수도 있습니다null
.containsKey
작업은이 두 경우를 구별 할 수 있습니다.
여기에서 사용 null
이 어떻게 복잡해질 수 있는지 알아보기 시작합니다 . 첫 번째 문장은 키가 매핑되지 않으면 null
반환 된다고 말합니다 . 두 번째 문은 키가 매핑 된 경우에도 있다고 null
할 수 도 반환.
반대로, 키와 값을 java.util.Hashtable
허용하지 않으면 서 일을 더 단순하게 유지 null
합니다. its V get(Object key)
가 반환 null
되면 키가 매핑되지 않았 음을 의미합니다.
나머지 API를 읽고 null
사용되는 위치와 방법을 찾을 수 있습니다. 이들이 항상 모범 사례 는 아니라는 점을 명심하십시오 .
일반적으로 말하자면 null
다음을 의미하는 특수한 값으로 사용됩니다.
메모리에 어떻게 표현됩니까?
자바? 걱정하지 마십시오. 그렇게하는 것이 가장 좋습니다.
null
좋은 가요 ?이것은 이제 경계 주관적입니다. 어떤 사람들 null
은 많은 프로그래머 오류를 피할 수 있다고 말합니다 . 어떤 사람들은 NullPointerException
자바처럼 잡는 언어에서는 프로그래머 오류로 실패 할 것이므로 사용하는 것이 좋다고 말합니다. 어떤 사람들 null
은 Null 객체 패턴 등 을 사용하여 피 합니다 .
이것은 자체적으로 큰 주제이므로 다른 질문에 대한 답변으로 가장 잘 논의됩니다.
나는 이것을 null
자신 의 발명가 인 CAR Hoare (Quicksort Fame) 의 인용으로 인용 할 것이다 :
나는 그것을 10 억 달러의 실수라고 부릅니다. 그것은
null
1965 년에 참조 의 발명이었다 . 그때, 나는 객체 지향 언어 (ALGOL W)로 참조를위한 최초의 포괄적 인 타입 시스템을 설계하고 있었다. 필자의 목표는 컴파일러가 자동으로 검사를 수행하여 모든 참조 사용이 절대적으로 안전하도록하는 것이 었습니다. 그러나null
구현하기가 쉽기 때문에 참조를 하려는 유혹에 저항 할 수 없었습니다 . 이로 인해 수많은 오류, 취약성 및 시스템 충돌이 발생했으며, 이는 아마도 지난 40 년 동안 수십억 달러의 고통과 피해를 야기했을 것입니다.
NIL
1960 년 에 LISP에는 null 참조가 있었으며 아마도 초기에는있었습니다. 그러나 Hoare가 실제로 그 인용에서 null 참조의 발명을 주장하려고 한다고 생각하지 않습니다 .
null은 무엇인가의 인스턴스입니까?
아닙니다. 그것이 모든 수업에 대해 null instanceof X
돌아 오는 이유 입니다 . ( 유형이 객체 유형 인 변수에 할당 할 수 있다는 사실에 속지 마십시오 . 엄밀히 말하면, 할당에는 암시 적 유형 변환이 포함됩니다 (아래 참조).false
X
null
'null'은 어떤 세트에 속합니까?
널 유형이 유일하고 유일한 널 유형이며, 여기서 널 유형은 다음과 같이 정의됩니다.
"특정 널 유형, 즉 표현식 널의 유형은 이름이 없습니다. 널 유형에는 이름이 없기 때문에 널 유형의 변수를 선언하거나 널 유형으로 캐스트 할 수 없습니다. 참조는 null 유형의 표현식에서 유일하게 가능한 값입니다 .null 참조는 항상 모든 참조 유형으로 캐스트 될 수 있습니다. 실제로 프로그래머는 널 유형을 무시하고 null이 단지 임의의 특수 리터럴 인 것처럼 가장 할 수 있습니다. 참조 유형. " JLS 4.1
널이란 무엇입니까?
위 참조. 일부 상황에서 null
"개체 없음"또는 "알 수 없음"또는 "사용할 수 없음"을 나타내는 데 사용되지만 이러한 의미는 응용 프로그램에 따라 다릅니다.
메모리에 어떻게 표현됩니까?
그것은 구현 null
에 따라 다르며 순수한 Java 프로그램 에서는 표현을 볼 수 없습니다 . (그러나 null
모든 Java 구현은 아니지만 대부분의 경우 0의 기계 주소 / 포인터로 표시됩니다.)
널이란 무엇입니까?
아무것도 아니다.
null은 무엇인가의 인스턴스입니까?
그것은 아무것도 아니기 때문에 그것은 아무것도 인스턴스가 될 수 없습니다.
null은 어떤 집합에 속합니까?
어떤 세트도 없습니다
메모리에 어떻게 표현됩니까?
일부 참조가 다음을 가리키는 경우 :
Object o=new Object();
힙 메모리에서 새로 작성된 오브젝트에 할당 된 공간이 있습니다. 그리고 o는 메모리에서 할당 된 공간을 가리 킵니다.
지금 o=null;
이것은 이제 o가 객체의 메모리 공간을 가리 키지 않음을 의미합니다.
Java에서 널 (tm)
C 및 C ++에서 "NULL"은 헤더 파일에 정의 된 상수이며 다음과 같은 값을 갖습니다.
0
또는:
0L
또는:
((void*)0)
컴파일러 및 메모리 모델 옵션에 따라 다릅니다. NULL은 C / C ++ 자체의 일부가 아닙니다.
Java (tm)에서 "null"은 키워드가 아니라 널 유형의 특수 리터럴입니다. int 또는 boolean과 같은 기본 유형으로 변환 할 수 없지만 모든 참조 유형으로 캐스트 할 수 있습니다. 널 리터럴은 반드시 0 값을 가질 필요는 없습니다. 그리고 널 유형으로 캐스트하거나이 유형의 변수를 선언하는 것은 불가능합니다.
바이트 코드 표현
Java null
는 직접 JVM을 지원합니다.이를 구현하기 위해 세 가지 명령이 사용됩니다.
aconst_null
:이 예에 변수를 설정 null
마찬가지로Object o = null;
ifnull
과 ifnonnull
:에 개체를 비교 예 null
에서와 같이if (o == null)
6 장 "Java Virtual Machine 명령어 세트" 는 null
다른 명령어에 미치는 영향에 대해 언급 NullPointerException
합니다.
2.4. "참조 유형 및 값" 은 다음 null
과 같은 일반적인 용어로 언급 됩니다.
참조 값은 특수 null 참조 일 수도 있습니다. 여기서 개체가없는 참조는 여기에서 null로 표시됩니다. null 참조는 초기에 런타임 유형이 없지만 모든 유형으로 캐스트 될 수 있습니다. 참조 유형의 기본값은 널입니다.
null
클래스의 인스턴스가 아닌 특수 값입니다. 이것은 다음 프로그램에 의해 설명됩니다.
public class X {
void f(Object o)
{
System.out.println(o instanceof String); // Output is "false"
}
public static void main(String[] args) {
new X().f(null);
}
}
null
의 인스턴스가 아니라는 것입니다 String
.
void f(String o)
더 의미가 있습니다.
Java의 null은 C ++의 nullptr과 비슷하거나 비슷합니다.
C ++의 프로그램 :
class Point
{
private:
int x;
int y;
public:
Point(int ix, int iy)
{
x = ix;
y = iy;
}
void print() { std::cout << '(' << x << ',' << y << ')'; }
};
int main()
{
Point* p = new Point(3,5);
if (p != nullptr)
{
p->print();
p = nullptr;
}
else
{
std::cout << "p is null" << std::endl;
}
return 0;
}
자바에서 동일한 프로그램 :
public class Point {
private int x;
private int y;
public Point(int ix, int iy) {
x = ix;
y = iy;
}
public void print() { System.out.print("(" + x + "," + y + ")"); }
}
class Program
{
public static void main(String[] args) {
Point p = new Point(3,5);
if (p != null)
{
p.print();
p = null;
}
else
{
System.out.println("p is null");
}
}
}
이제 위의 코드에서 Java의 null이 무엇인지 이해합니까? 그렇다면 C / C ++에서 포인터를 배우는 것이 좋습니다. 그러면 이해할 것입니다.
C에서 C ++와 달리 nullptr은 정의되지 않았지만 대신 NULL이 사용되며 C ++에서도 사용될 수 있지만 C ++에서 NULL은 항상 포인터와 관련이 있기 때문에 NULL보다 더 선호됩니다. 따라서 C ++에서 접미사 "ptr"은 단어 끝에 추가되었으며 모든 문자는 이제 소문자이지만 중요하지 않습니다.
Java에서는 기본이 아닌 클래스 유형의 모든 변수가 항상 해당 유형의 객체를 참조하거나 상속되며 null은 null 클래스 객체 참조이지만 null 포인터는 아닙니다. Java에는 "포인터"가 없기 때문에 클래스에 대한 참조가 있기 때문입니다. 객체는 대신 사용되며 Java의 null은 클래스 객체 참조와 관련이 있으므로 "nullref"또는 "nullrefobj"라고도 할 수 있지만이 길이는 길기 때문에 "null"이라고합니다.
C ++에서는 선택적 멤버 / 변수, 즉 값이없는 멤버 / 변수에 포인터와 nullptr 값을 사용할 수 있습니다. 값 이 없으면 nullptr과 같습니다. 예를 들어 Java의 null을 사용할 수 있습니다.
내 의견으로는 자바에서 null을 보는 흥미로운 방법은 정보의 부재를 나타내지 않고 단순히 모든 유형의 참조에 할당 할 수있는 리터럴 값으로 보는 것입니다. 정보가 없다고 생각하면 a1 == a2가 true라는 것은 실제로 모든 객체를 가리킬 수 있으므로 의미가 없습니다 (둘 다 null 값이 할당 된 경우). 어떤 객체를 가리켜 야하는지 모르겠다.) 그런데 null == null은 java에서 true를 반환합니다. 예를 들어 Java가 SQL : 1999와 같으면 null = = null은 알 수없는 값을 반환합니다 (SQL : 1999의 부울 값은 세 가지 값을 취할 수 있습니다 : true, false 및 unknown이지만 실제로는 unknown은 실제 시스템에서 null로 구현됩니다) ... http://en.wikipedia.org/wiki/SQL
JLS에서 공식적으로 모든 질문에 대답하는 짧고 정확한 답변 :
3.10.7. 널 리터럴
널 유형에는 널 문자 널로 표시되는 널 참조 인 ASCII 값으로 구성된 하나의 값이 있습니다.
널 리터럴은 항상 널 유형입니다.
널에 지정된 유형의 참조 만 할당됩니다. 참조에 값 (객체)을 할당하지 않습니다. 이러한 할당은 JVM이 참조하는 양과 할당 할 메모리 영역에 따라 다릅니다.