null을 ternary 연산자에 허용된 int로 반환하지만 문이 아닌 경우
다음의 간단한 Java 코드를 살펴보자.
public class Main {
private int temp() {
return true ? null : 0;
// No compiler error - the compiler allows a return value of null
// in a method signature that returns an int.
}
private int same() {
if (true) {
return null;
// The same is not possible with if,
// and causes a compile-time error - incompatible types.
} else {
return 0;
}
}
public static void main(String[] args) {
Main m = new Main();
System.out.println(m.temp());
System.out.println(m.same());
}
}
자바코드를 사용한다temp()
메소드는 함수의 반환 유형이 다음과 같더라도 컴파일러 오류를 발생시키지 않음int
그리고 우리는 그 값을 반환하려고 한다.null
)return true ? null : 0;
) 컴파일할 때, 이는 분명히 실행 시간 예외를 야기한다.NullPointerException
.
그러나, 3차 연산자를 1차 연산자로 대표한다면, 같은 것은 잘못된 것으로 보인다.if
성명서(앞과 같이)same()
method)는 컴파일 시간 오류를 발생시킨다! 왜?
컴파일러가 해석하다.null
에 대한 으로서.Integer
는 조건부 연산자에 대해 자동 복싱/해제(Java Language Specification, 15.25) 규칙을 적용하고 행복하게 이동한다.이렇게 하면NullPointerException
런타임에, 그것을 시도해봄으로써 확인할 수 있다.
내 생각엔 자바 컴파일러가 해석한 것 같아true ? null : 0
의 하나로Integer
으로 암시로 할 수 표현이다.int
, 아마도 주는 것NullPointerException
.
두 번째 경우, 그 표현은null
특수 null 타이피의 코드인 경우return null
유형 불일치를 만든다.
사실, 모든 것이 자바 언어 사양에 설명되어 있다.
조건식 유형은 다음과 같이 결정된다.
- 두 번째 피연산자와 세 번째 피연산자가 같은 유형(null 유형일 수 있음)을 갖는 경우, 그것은 조건식의 유형이다.
그러므로 그대 속에 있는 "null"은(true ? null : 0)
int type을 가져온 다음 Nument에 자동 저장된다.
이와 같은 것을 시도하여 이를 확인하십시오.(true ? null : null)
컴파일러 오류가 발생할 것이다.
의 .if
, ,, ,null
참조는 a로 취급되지 않는다.Integer
그것을 그렇게 해석하도록 강요하는 표현에 참여하지 않기 때문에 참조한다.따라서 오류는 더 명확하게 유형 오류이기 때문에 컴파일 시간에 쉽게 포착할 수 있다.
조건부 운영자에 대해서는, 자바 언어 규격 제15.25조 "조건 운영자? :
" 형식 변환을 적용하는 방법에 대한 규칙에서 다음과 같이 잘 대답한다.
- 두 번째 피연산자와 세 번째 피연산자가 같은 유형(null 유형일 수 있음)을 갖는 경우, 그것은 조건식의 유형이다.
다음 이유로 적용되지 않음null
아니다int
.
- 두 번째 및 세 번째 피연산자 중 하나가 부울 유형이고 다른 피연산자 유형이 부울 유형인 경우 조건식 유형은 부울 유형이다.
둘 다 없기 때문에 적용되지 않음null
아닌int
이다boolean
또는Boolean
.
- 두 번째 및 세 번째 피연산자 중 하나가 null 유형이고 다른 피연산자 유형이 참조 유형인 경우 조건부 식의 유형은 해당 참조 유형이다.
다음 이유로 적용되지 않음null
null 형식인 경우int
참조 유형이 아니다.
- 그렇지 않으면, 두 번째와 세 번째 피연산자가 숫자형식으로 변환할 수 있는 유형(제5.1.8조)을 가지고 있다면, 다음과 같은 몇 가지 경우가 있다. […]
적용 대상:null
숫자형식으로 변환할 수 있는 것으로 취급되며, 제5.1.8조의 "복스 해제 변환"에 정의되어 있다.NullPointerException
.
먼저 명심해야 할 것은 자바 3차 연산자는 '유형'을 가지고 있으며, 이것이 두 번째 또는 세 번째 파라미터의 실제/실제 유형이 무엇이든 간에 컴파일러가 결정하고 고려할 사항이라는 점이다.몇 가지 요인에 따라 3차 연산자 유형은 자바 언어 규격 15.26에 설명된 바와 같이 다른 방식으로 결정된다.
위의 질문에서 우리는 마지막 경우를 고려해야 한다.
그렇지 않으면 두 번째 피연산자와 세 번째 피연산자는 각각 S1과 S2 유형이다.T1을 S1에 복싱 변환을 적용하여 발생하는 유형으로 하고, T2를 S2에 복싱 변환을 적용하여 발생하는 유형으로 한다.조건부 표현식의 형식은 lub(T1, T2) (제15.12.2.7조)에 포획 변환(제5.1.10조)을 적용한 결과다.
캡쳐 변환(제5.1.10조)을 적용하고, 무엇보다도 ub(T1, T2)를 적용하면, 이것은 단연코 가장 복잡한 경우다.
쉬운 영어로 그리고 극단적으로 단순화한 후에 우리는 그 과정을 두 번째와 세 번째 파라미터의 "Least Common Superclass"(예, LCM을 생각한다)를 계산하는 것으로 설명할 수 있다.이것은 우리에게 3차 연산자 "유형"을 줄 것이다.다시 말하지만, 내가 방금 말한 것은 극단적으로 단순화되었다(여러 개의 공통 인터페이스를 구현하는 클래스를 고려한다).
예를 들어, 다음을 시도하는 경우:
long millis = System.currentTimeMillis();
return(true ? new java.sql.Timestamp(millis) : new java.sql.Time(millis));
조건식의 결과 유형이java.util.Date
의 'Least Common Superclass'인 만큼, 'Least Common Superclass'의 'Least Common Superclass'Timestamp
/Time
짝을 짓다
이후null
어떤 할 수 슈퍼클래스는 '어르렁어르렁' 이며, '최저공통 슈퍼클래스'는 '어르렁어르렁'이다.Integer
type ) class educed의 조건부 (the conditional experiator)의 이 될 이다.그런 다음 반환 값은 null 포인터 유형의 포인터가 된다.Integer
그리고 그것이 3차 운영자에 의해 반환될 것이다.
런타임에 Java Virtual Machine이 상자를 해제할 때Integer
a NullPointerException
던져지다이는 JVM이 함수를 호출하려고 시도하기 때문에 발생한다.null.intValue()
어디에null
자동 포싱의 결과야
내 생각에는 (그리고 내 의견이 자바 언어 명세서에 나와 있지 않기 때문에 많은 사람들이 어쨌든 틀렸다고 생각할 것이다) 컴파일러는 당신의 물음에 있는 표현을 평가하는데 서투른 일을 한다.네가 쓴 걸 보면true ? param1 : param2
컴파일러는 첫 번째 매개변수를 즉시 결정해야 한다.null
- 반환될 것이며 컴파일러 오류를 발생시킬 것이다.이것은 당신이 글을 쓸 때와 다소 비슷하다.while(true){} etc...
의 밑에 을 하고, 을 일일(일日)으로 플래그하여 flags일( flags日)은 에에 대하(大下)이다.Unreachable Statements
.
두 번째 경우는 꽤 간단하고 이 대답은 이미 너무 길다...;)
수정:
또 다른 분석 후에 나는 내가 a라고 말한 것이 잘못되었다고 믿는다.null
가치는 어떤 것에나 박스화/자동화 될 수 있다.정수 클래스에 대해 말하자면, 명시적 권투는 그 클래스를 호출하는 데 있다.new Integer(...)
건설업자 또는 아마도Integer.valueOf(int i);
(이 버전을 어디선가 찾았어.)전자는 a를 던질 것이다.NumberFormatException
(그리고 이런 일은 일어나지 않는다) 그러나 두번째는 단지 그 이후로 말이 되지 않을 것이다.int
할 수 없다null
...
사실 첫 번째 경우에는 그 표현이 평가될 수 있는데, 컴파일러가 알고 있기 때문에 반드시 그 표현을 평가해야 한다.Integer
그러나 두 번째 경우에는 반환 값의 유형(null
할 수 할 수 은 단정할 수 없으므로 편찬할 수 없다.을 에베라면에 캐스팅한다면.Integer
암호는 컴파일될 것이다.
private int temp() {
if (true) {
Integer x = null;
return x;// since that is fine because of unboxing then the returned value could be null
//in other words I can say x could be null or new Integer(intValue) or a intValue
}
return (true ? null : 0); //this will be prefectly legal null would be refrence to Integer. The concept is one the returned
//value can be Integer
// then null is accepted to be a variable (-refrence variable-) of Integer
}
이거 어때:
public class ConditionalExpressionType {
public static void main(String[] args) {
String s = "";
s += (true ? 1 : "") instanceof Integer;
System.out.println(s);
String t = "";
t += (!true ? 1 : "") instanceof String;
System.out.println(t);
}
}
결과는 참, 참이다.
Eclipse 색상은 조건식의 1을 자동화된 것으로 코드화한다.
내 추측으로는 컴파일러가 표현식의 반환 유형을 Object로 보고 있는 것 같다.
'programing' 카테고리의 다른 글
C와 C++에서 거의 동일한 코드 간의 실행 시간에서 큰 차이(x9) (0) | 2022.04.26 |
---|---|
템플릿 내에서 값을 반환하는 기능을 사용하는 방법브룩스, 브룩스 (0) | 2022.04.26 |
Vuex 업데이트 상태 (0) | 2022.04.26 |
Enum과 Define 문 간의 차이 (0) | 2022.04.26 |
String을 사용하는 것이 더 좋은 습관인가?문자열 위에 형식 자바에서 연결하시겠습니까? (0) | 2022.04.26 |