Java ?: 연산자 란 무엇이며 어떤 역할을합니까?


161

나는 2 년 동안 Java로 일해 왔지만 최근까지는이 구성을 뛰어 넘지 못했습니다.

int count = isHere ? getHereCount(index) : getAwayCount(index);

이것은 아마도 매우 간단한 질문이지만 누군가 설명 할 수 있습니까? 어떻게 읽습니까? 어떻게 작동하는지 잘 알고 있습니다.

  • 경우 isHere사실이다, getHereCount()라고,
  • 경우 isHere거짓 getAwayCount()이라고합니다.

옳은? 이 구조는 무엇입니까?


2
이 질문의 C ++ 버전에 대해서는 stackoverflow.com/questions/795286/what-does-do-in-c 도 참조하십시오 (실제로 어제 요청 된 경우).
Michael Myers

2
C / C ++ / Java 세계는 추악하고 혼란스럽고 역병처럼 피할 수있는 사람들과 당신이 정말로 C, C ++ 또는 Java를 모른다고 주장 할 수 없다고 생각하는 사람들 사이에 균등하게 나누어 져 있습니다. 그것을 인식하고 생각을 멈추지 않고 사용할 수 없습니다.
Paul Tomblin

3
가장 명확하고 간단한 경우를 넘어서 사용하는 것은 일반적으로 Java에서 잘못된 형식으로 간주됩니다. 당신이 그들을 중첩 발견하면, 당신은 탈출구입니다. 다른 한편으로, 빠르고 영리한 코드가 선명도보다 높은 C 문화에서는 허용되는 것으로 간주됩니다.
Yishai

17
answer_to_question = (인식 _ 운영자)? (social_acceptance) : (condescending_finger_wag)
Dan

자세한 내용 은 리소스를 참조하십시오.
시바

답변:


189

그렇습니다.

int count;
if (isHere)
    count = getHereCount(index);
else
    count = getAwayCount(index);

이를 조건부 연산자 라고합니다 . Java, C, C ++ 및 기타 여러 언어에서 유일하게 삼항 (3 인수) 연산자이기 때문에 많은 사람들이 이것을 잘못 삼항 연산자 라고 부릅니다 . 그러나 이론적으로있을 수있는 단 하나의있을 수있는 반면, 또 다른 삼항 연산자가 될 조건 연산자 .

공식 명칭은 Java 언어 사양에 나와 있습니다 .

§15.25 조건부 연산자? :

조건부 연산자 ? :는 한 표현식의 부울 값을 사용하여 두 개의 다른 표현식 중 어떤 것을 평가할지 결정합니다.

두 가지 모두 반환 값이있는 메소드로 연결되어야합니다.

두 번째 또는 세 번째 피연산자 표현식이 void 메소드를 호출하는 것은 컴파일 타임 오류입니다.

실제로, 표현 문의 문법 ( §14.8 )에 의해, void 메소드의 호출이 나타날 수있는 어떤 상황에서도 조건식이 나타나는 것은 허용되지 않습니다.

따라서 void 메소드 인 경우 doSomething()이를 doSomethingElse()압축 할 수 없습니다.

if (someBool)
    doSomething();
else
    doSomethingElse();

이것으로 :

someBool ? doSomething() : doSomethingElse();

간단한 단어 :

booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse 

나는 맨 아래쪽이 무엇을하는지 이해하지 못한다. 나는 당신과 모두를 믿습니다. 원본과 동일하게 보입니다. 값을 반환하거나 반환하지 않을 수있는 다른 함수를 호출하고 다음 코드 세트를 실행할 수 있기 때문입니까?
johnny

8
doSomething () 및 doSomethingElse ()가 void 메소드라고 가정합니다. 스펙의 마지막 부분은 삼항 연산자 값을 리턴 해야 하므로 피연산자 중 어느 것도 void 메소드가 될 수 없다는 것입니다.
Michael Myers

그것은 그것보다 조금 더 말합니다. void 메소드 COULD가 나타나는 곳에서는 조건부 연산자가 허용되지 않습니다. 따라서 예를 들어 다음과 같은 문장이 있습니다. VALID : String x = (false)? "X": "Y"; 유효하지 않음 : (거짓)? "X": "Y";
kenj0418

4
오바마를 "대통령"이라고 언급하는 것은 잘못되어 있지 않은 것처럼 (2016 년),이를 "삼항 연산자"라고 부르는 것은 잘못되지 않습니다.
Dawood ibn Kareem

2
@DawoodibnKareem 나는 마이클이 의도적으로 포함 생각 the의 italicisation에 the ternary operator, 그리고 그건 그, 오류없는 그가 의미하는 ternary operator오류입니다. 삼항 연산자는 마이클이 말한대로, 그것은 다시 잘못된 무엇 마이클 말입니다 다른 삼항 연산자있을 수 없다 가정을 이끌 수있는, 단 하나, 내가 동의 하겠지만, 그 의미, 그것은 수 잘못된 가정.
Ghoti와 칩

32

다른 사람들은 이것을 합리적인 정도로 대답했지만 종종 "삼항 연산자"라는 이름으로 대답했습니다.

나는 pedant이기 때문에 연산자의 이름이 조건부 연산자 또는 "조건부 연산자? :"임을 분명히하고 싶습니다. 그것은이다 삼항 연산자 (이 세 개의 피연산자를 가지고있는 것을) 순간에 자바에있는 유일한 삼항 연산자로 발생합니다.

그러나 스펙은 그 이름이 조건부 연산자 또는 "조건부 연산자? :"라는 것이 분명합니다. 피연산자가 몇 개가 아닌 연산자의 동작을 어느 정도 (조건 평가) 나타내는 것으로 표시되므로 그 이름으로 호출하는 것이 더 명확하다고 생각합니다.


3
이 답변은 기술적으로 정확합니다. 그러나 삼항 연산자는 하나뿐이므로 종종 삼항 연산자라고합니다. 이 이름이 연산자의 완전한 의미를 전달하지는 않지만 붙어있는 이름입니다. "삼항 연산자"라는 이름을 언급하면 ​​프로그래머가 말하는 내용을 알고 있습니다. 언급 한 사양은이 연산자를보다 유용한 정보 인 "Ternary Conditional"이라고도합니다. java.sun.com/docs/books/jls/third_edition/html/…
Gary

17
정의 된 이름으로 무언가를 호출 할 가치가 있다고 생각합니다. 특히 Java가 다른 삼항 연산자를 얻는 경우 "조건부 연산자"라는 용어를 사용하는 사람들은 "삼항 연산자"라고 말하는 사람들과 달리 여전히 정확하고 모호하지 않습니다. 그렇습니다. "삼항 연산자"라는 문구가 멈췄습니다. "객체가 참조로 전달되었다"는 주장을 바로 잡을 때와 같이 제 답변은 "고착 해제"하려는 노력의 일부입니다.
Jon Skeet

1
세 개의 "조건부 연산자"에 대해 말하지만 하나의 "삼항 연산자"에 대해서만 설명하는 Oracle의이 페이지로 안내 할 수 있습니까? 어떤 연산자를 의미하는지 명확하게하려면 대부분의 사람들이 사용하는 이름을 사용하는 것이 좋습니다. (예, 주최자가 마지막 설거지를하는 것처럼 파티에 참석한다는 것을 알고 있습니다).
Dawood ibn Kareem

@DavidWallace : "조건부 연산자? :"를 사용하는 것이 좋습니다. IMO-이를 명확히하기 위해 편집합니다. 그러나 나는 사람들이 행동과 아무런 관련이없는 연산자 (얼마나 많은 피연산자)의 한 측면에 초점을 맞추기보다는 연산자의 실제 이름을 사용하도록 설득 할 가치가 있다고 생각합니다. ( &&조건부 및 연산자 및 ||조건부 또는 연산자 를 호출하는 사양보다 자습서가 정확하지 않은 경우도 드물지 않지만 , "조건부 연산자"만 사용합니다 ?:.
Jon Skeet

모르겠어요 누군가가 "조건부 연산자"라고 말하면 그 의미가 무엇인지 잘 모르겠습니다. 내가 (당신으로부터 세상의 반대편에서) 온 사람들은 이것을 이것을 부르지 않습니다. 그들이 "삼항 연산자"또는 "후크 연산자"라고 말하면 이해합니다. 사람들의 대화 방식을 바꾸고 싶은 당신의 야망에 감탄합니다. 누구나 할 수 있다면 그것은 당신입니다. 그러나 나는 많은 희망을 가지거나 많은 요점을 보지 못했습니다.
Dawood ibn Kareem

17

Sun Java Specification 에 따르면이를 조건부 연산자라고합니다. 섹션 15.25를 참조하십시오. 당신은 그것이 무엇을하는 것이 옳습니다.

조건부 연산자? : 한 표현식의 부울 값을 사용하여 두 개의 다른 표현식 중 어느 것을 평가할지 결정합니다.

조건부 연산자는 구문 상 오른쪽 연관 (오른쪽에서 왼쪽으로 그룹화)이므로 a? b : c? d : e? f : g는 a? b : (c? d : (e? f :지)).

ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression

조건부 연산자에는 세 가지 피연산자 표현식이 있습니다. ? 첫 번째 식과 두 번째 식 사이에가 나타나고 :가 두 번째 식과 세 번째 식 사이에 나타납니다.

첫 번째 표현식은 부울 또는 부울 유형이어야합니다. 그렇지 않으면 컴파일 타임 오류가 발생합니다.


5
int count = isHere ? getHereCount(index) : getAwayCount(index);

의미 :

if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

5

정확하게 정확하지 않은 :

  1. isHere가 true 인 경우 getHereCount () 의 결과리턴됩니다.
  2. otheriwse getAwayCount () 의 결과반환됩니다

"반환"은 매우 중요합니다. 즉, 메소드 값을 리턴 해야 하며 해당 값을 어딘가에 지정 해야합니다 .

또한 구문 적으로 if-else 버전과 동일 하지 않습니다 . 예를 들면 다음과 같습니다.

String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;

if-else로 코딩하면 항상 더 많은 바이트 코드가 생성됩니다.


javac가 동일한 바이트 코드를 생성 할 자유가 있다고 생각합니다. 동일하지 않은 모호한 경우가있는 것은 맞습니다.
Tom Hawtin-tackline

물론입니다. 나에게 조건 연산자의 진정한 장점은 내가 제시 한 예입니다. 대안은 : // gasp !! 문자열 온도 = str1; 만약 (확인) temp + = str2; 그렇지 않으면 temp + = str3; 온도 + = str4; 반환 온도; 또는 StringBuilder 추가 작업을 핸드 코딩합니다. 첫 번째는 심각한 효율성 문제를 겪고 두 번째는 너무 장황하며 많은 이익을 얻지 못하는 힘든 노력입니다.
RichN

4

3 차 조건부; 토마토, tomatoh. 정말 유용한 것은 변수 초기화입니다. (나처럼) 변수가 정의 된 곳에서 변수를 초기화하는 것을 좋아한다면 조건부 삼항 연산자 (둘 다)는 값에 대한 조건이있는 경우에 그렇게 할 수 있습니다. 특히 최종 분야에서 주목할 만하지 만 다른 곳에서도 유용합니다.

예 :

public class Foo {
    final double    value;

    public Foo(boolean positive, double value) {
        this.value = positive ? value : -value;
    }
}

어떤 이름 으로든 그 연산자가 없으면 필드를 최종 값으로 만들거나 단순히 초기화하는 함수를 작성해야합니다. 실제로, 그것은 옳지 않습니다-적어도 Java에서는 if / else를 사용하여 초기화 할 수 있습니다. 그러나 나는이 청소기를 찾습니다.



3

이 구성 을 컴퓨터 과학 및 프로그래밍 기술에서 3 차 연산자 라고 합니다.
그리고 Wikipedia 는 다음과 같은 설명을 제안합니다.

컴퓨터 과학에서 3 항 연산자 (때로는 3 차 연산자라고 잘못 부름)는 세 가지 인수를 취하는 연산자입니다. 인수와 결과는 다른 유형일 수 있습니다. C와 유사한 구문을 사용하는 많은 프로그래밍 언어에는 조건부 표현식을 정의하는 삼항 연산자? :가 있습니다.

Java뿐만 아니라이 구문은 PHP, Objective-C에서도 사용할 수 있습니다.

다음 링크 에서는 다음 설명을 제공하며 이해하기에 조용합니다.

삼항 연산자는 3 개의 입력에서 작동하는 작업입니다. if-else 문의 바로 가기이며 조건부 연산자라고도합니다.

Perl / PHP에서는 다음과 같이 작동합니다.
boolean_condition ? true_value : false_value

C / C ++에서는 다음과 같이 작동합니다.
logical expression ? action for true : action for false

이것은 너무 복잡하지 않은 일부 논리 조건에서 읽을 수 있습니다. 그렇지 않으면 조건부 논리의 의도 된 조합으로 If-Else 블록 을 사용하는 것이 좋습니다 .

이 Ternary 연산자를 사용하면 If-Else 블록 을 하나의 코드 명령문 행으로 단순화 할 수 있습니다 .
예를 들어 :

if ( car.isStarted() ) {
     car.goForward();
} else {
     car.startTheEngine();
}

다음과 같을 수 있습니다.

( car.isStarted() ) ? car.goForward() : car.startTheEngine();

우리가 당신의 진술을 언급한다면 :

int count = isHere ? getHereCount(index) : getAwayCount(index);

실제로 다음 If-Else 블록 과 100 % 동일합니다 .

int count;
if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

그게 다야!
이것이 누군가에게 도움이 되었기를 바랍니다!
건배!


2

옳은. 그것은 것 이라고 삼항 연산자 . 일부는 조건 연산자 라고도합니다 .


9
Alice In Wonderland를 인용하면 3 항 연산자라고하지만 이름은 조건부 연산자입니다.
Paul Tomblin

그러나 그 이름을 물음표 콜론 연산자라고합니다.
Michael Myers

1
이름 지정 사운드는 약간 C ++ ish입니다. 물음표 콜론 연산자? :( 하나의 토큰)를 Elvis 연산자라고합니다.
Tom Hawtin-tackline

2

삼항 연산자 (? :)

The ternary operator is an operator that takes three arguments. The first 
argument is a comparison argument, the second is the result upon a true 
comparison, and the third is the result upon a false comparison.

1

조건부 연산자와 유사한 일부 새 연산자 에 대한 제안 에 관심이있을 수 있습니다 . null 안전 연산자는 다음과 같은 코드를 활성화합니다.

String s = mayBeNull?.toString() ?: "null";

자동 언 박스가 발생하는 경우 특히 편리합니다.

Integer ival = ...;  // may be null
int i = ival ?: -1;  // no NPE from unboxing

JDK 7의 "프로젝트 코인"에서 추가 고려 대상 으로 선정 되었습니다 .


이 운영자는 Project Coin에서 내가 가장 좋아하는 사람이 아닙니다. 읽기에 직관적이지 않고 제한적으로 유용하며 모든 나갈 때 평범하지 않습니다. 어쩌면 그것은 나에게 자랄 것입니다.
Michael Myers

실제로 큰 팬도 아닙니다. 그것은 Neal Gafter 제안이며, 일반적인 Java 프로그래머와는 다른 것을 보는 경향이 있으며, 일반적인 Java 프로그래머와는 다른 것을 보는 경향이 있습니다. null에 대해 약간의 도움을 원할 수있는 유일한 곳은 foreach 루프에 있으며 iterable이 null인지 테스트하고 자동 unboxing입니다.
erickson

IIRC <닐은 제안하지 않았다. 그는 방금 제안서를 작성하는 간단한 예제로 사용했습니다. 프로젝트 코인 메일 링리스트 아카이브에 대한 자세한 내용.
Tom Hawtin-tackline

방금 제안서의 소개를 읽었을뿐입니다. Joda의 Stephen Colebourne이며 "Java 7이 없습니다"라는 명성이 있습니다.
erickson

1

실제로 3 개 이상의 인수가 필요할 수 있습니다. 예를 들어 숫자가 양수, 음수 또는 0인지 확인하려면 다음을 수행하십시오.

String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";

if, else if, else를 사용하는 것보다 낫습니다.


0

조건부 연산자이며 if 문을 작성하는 간결한 방법 이상입니다.

값을 리턴하는 표현식이므로 다른 표현식의 일부로 사용할 수 있습니다.


0

그래 정확 해. ? : 일반적으로 "삼항 조건부 연산자"라고하며 종종 "삼항 연산자"라고도합니다. 조건부 인 경우 표준의 약식 버전입니다.

삼항 조건 연산자


0

나는이 연산자를 정말로 좋아하지만 독자는 고려해야합니다.

코드 압축은 코드를 읽는 데 걸리는 시간과 항상 균형을 이루어야하며, 이는 심각한 결함이 있습니다.

우선 Original Asker 's case가 있습니다. 그는 단지 한 시간 동안 그것에 대해 게시하고 답변을 읽었습니다. 평생 동안 모든? :를 if / then으로 쓰는 데 저자가 더 오래 걸렸을 것입니다. 확실히 한 시간이 아닙니다.

둘째, C와 같은 언어에서는 조건부 조건이 첫 번째 줄임을 단순히 아는 습관이 있습니다. Ruby를 사용할 때 이것을 발견하고 다음과 같은 줄을 보았습니다.

callMethodWhatever(Long + Expression + with + syntax) if conditional

내가 오랫동안 루비 사용자라면 아마이 라인에 문제가 없었을 것이다. 그러나 "callMethodWhatever"를 라인의 첫 번째로 보았을 때 C에서 나온다면, 그것이 실행될 것으로 기대한다. ? :는 덜 까다 롭지 만 여전히 독자를 버릴 정도로 특이합니다.

그러나 이점은 줄의 1 칸에 3 줄 if 문을 쓸 수있을 때 배가 정말 멋진 느낌입니다. :) 그러나 솔직히 말해서, 사람들의 90 %가 단순히 희귀 성 때문에 더 쉽게 읽을 수있는 것은 아닙니다.

부울과 값을 기반으로하는 할당 일 때 문제가 없지만 쉽게 남용 될 수 있습니다.


0

조건식은 완전히 다른 스타일이며 명령문에 명시적인 if가 없습니다.

구문은 다음과 같습니다. boolean-expression? expression1 : expression2;

이 조건식의 결과는

부울 표현식이 참인 경우 expression1;

그렇지 않으면 결과는 expression2입니다.

더 많은 수의 변수 num1 및 num2를 max에 지정한다고 가정하십시오. 조건식을 사용하여 간단히 명령문을 작성할 수 있습니다. max = (num1> num2)? num1 : num2;

참고 : 기호? : : 조건식으로 함께 나타납니다. 조건부 연산자를 구성하며 세 개의 피연산자를 사용하기 때문에 삼항 연산자라고도합니다. Java에서 유일하게 삼항 연산자입니다.

인용 : Y. Daniel Liang의 Java Programming 10th Edition 소개 페이지 126-127

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