it-swarm-ko.tech

Java가 연산자 오버로딩을 제공하지 않는 이유는 무엇입니까?

C++에서 Java에 이르기까지 명백한 질문에 Java에 연산자 오버로딩이 포함되지 않은 이유가 무엇입니까?

Complex a, b, c; a = b.add(c);보다 Complex a, b, c; a = b + c;가 훨씬 간단하지 않습니까?

이것에 대한 알려진 이유가 있습니까? not 연산자 오버로딩을 허용하는 유효한 인수가 있습니까? 그 이유는 임의적입니까, 아니면 시간을 잃었습니까?

384
rengolin

a이 참조하는 객체의 이전 값을 덮어 쓰려고한다고 가정하면 멤버 함수를 호출해야합니다.

Complex a, b, c;
// ...
a = b.add(c);

C++에서이 표현식은 스택에 세 개의 (3) 개의 객체를 만들고 추가를 수행하고 임시 객체의 결과 값을 기존 객체 a복사하도록 컴파일러에 지시합니다.

그러나 Java에서 operator=는 참조 유형에 대해 값 복사를 수행하지 않으며 사용자는 값 유형이 아닌 새 참조 유형 만 작성할 수 있습니다. 따라서 Complex이라는 사용자 정의 유형의 경우 할당은 기존 값에 대한 참조를 복사하는 것을 의미합니다.

대신 다음을 고려하십시오.

b.set(1, 0); // initialize to real number '1'
a = b; 
b.set(2, 0);
assert( !a.equals(b) ); // this assertion will fail

C++에서는이 값을 복사하므로 비교 결과가 동일하지 않습니다. Java에서 operator=는 참조 복사를 수행하므로 ab은 이제 동일한 값을 참조합니다. 결과적으로, 객체는 그 자체와 동등하다고 비교되기 때문에 비교는 'equal'을 생성합니다.

복사본과 참조의 차이는 연산자 오버로딩의 혼란을 증가시킵니다. @Sebastian이 언급했듯이 Java와 C #은 모두 값과 참조 평등을 별도로 처리해야합니다. operator+는 값과 객체를 처리하지만 operator=는 이미 참조를 처리하기 위해 구현되었습니다.

C++에서는 한 번에 한 종류의 비교 만 다루어야하므로 혼동을 덜 일으킬 수 있습니다. 예를 들어 Complex에서 operator=operator==는 모두 값에 대해 작업하고 있습니다. 값 복사와 값 비교가 각각 있습니다.

17
Aaron

연산자 오버로드에 대해 불만을 제기하는 게시물이 많습니다.

이 개념에 대한 대안적인 관점을 제시하면서 "연산자 오버로딩"개념을 명확히해야한다고 느꼈습니다.

코드 난독 화?

이 주장은 오류입니다.

난독 화는 모든 언어에서 가능합니다 ...

연산자 오버로드를 통해 C++ 에서처럼 함수/메소드를 통해 C 또는 Java 코드를 쉽게 이해할 수 있습니다.

// C++
T operator + (const T & a, const T & b) // add ?
{
   T c ;
   c.value = a.value - b.value ; // subtract !!!
   return c ;
}

// Java
static T add (T a, T b) // add ?
{
   T c = new T() ;
   c.value = a.value - b.value ; // subtract !!!
   return c ;
}

/* C */
T add (T a, T b) /* add ? */
{
   T c ;
   c.value = a.value - b.value ; /* subtract !!! */
   return c ;
}

... Java의 표준 인터페이스에서도

또 다른 예제를 보자 --- Java에서 Cloneableinterface 를 보자.

이 인터페이스를 구현하는 객체를 복제해야합니다. 그러나 거짓말을 할 수 있습니다. 다른 객체를 만듭니다. 사실,이 인터페이스는 너무 약해서 재미있는 것만 큼 다른 유형의 객체를 모두 반환 할 수 있습니다.

class MySincereHandShake implements Cloneable
{
    public Object clone()
    {
       return new MyVengefulKickInYourHead() ;
    }
}

Cloneable인터페이스가 악용되거나 난독 화 될 수 있으므로 동일한 근거로 금지되어야합니까? C++ 연산자 오버로드가 있어야합니까?

우리는 MyComplexNumber클래스의 toString() 메소드를 오버로드하여 오늘의 문자열 화 된 시간을 반환하도록 할 수 있습니다. toString() 오버로드도 금지되어야합니까? MyComplexNumber.equals를 임의 값을 반환하거나 피연산자를 수정하는 등의 작업을 할 수 있습니다.

C++이나 다른 언어에서와 마찬가지로 Java에서는 코드를 작성할 때 프로그래머가 최소한의 의미를 존중해야합니다. 즉, add함수를 구현하여 Cloneable클론 구현 메소드와 ++ 연산자를 증가시키는 것입니다.

어쨌든 난독 화가 뭐야?

이제 원시 자바 메소드를 통해서조차도 코드를 파괴 할 수 있다는 것을 알았으므로 C++에서 연산자 오버로딩을 실제로 사용할 수 있는지 자문 해 볼 수 있습니다.

명확하고 자연스러운 표기법 : 연산자 대 오버로딩?

자바와 C++의 "동일한"코드를 사용하여 어떤 코딩 스타일이 더 명확한지를 알기 위해 아래에서 비교해 보겠습니다.

자연 비교 :

// C++ comparison for built-ins and user-defined types
bool    isEqual          = A == B ;
bool    isNotEqual       = A != B ;
bool    isLesser         = A <  B ;
bool    isLesserOrEqual  = A <= B ;

// Java comparison for user-defined types
boolean isEqual          = A.equals(B) ;
boolean isNotEqual       = ! A.equals(B) ;
boolean isLesser         = A.comparesTo(B) < 0 ;
boolean isLesserOrEqual  = A.comparesTo(B) <= 0 ;

연산자 오버로드가 제공되는 한 A와 B는 C++에서 어떤 유형이든 사용할 수 있습니다. 자바에서 A와 B가 프리미티브가 아니면 코드는 원시와 비슷한 객체 (BigInteger 등)의 경우에도 매우 혼란 스러울 수 있습니다.

자연 배열/컨테이너 접근 자 및 subscripting :

// C++ container accessors, more natural
value        = myArray[25] ;         // subscript operator
value        = myVector[25] ;        // subscript operator
value        = myString[25] ;        // subscript operator
value        = myMap["25"] ;         // subscript operator
myArray[25]  = value ;               // subscript operator
myVector[25] = value ;               // subscript operator
myString[25] = value ;               // subscript operator
myMap["25"]  = value ;               // subscript operator

// Java container accessors, each one has its special notation
value        = myArray[25] ;         // subscript operator
value        = myVector.get(25) ;    // method get
value        = myString.charAt(25) ; // method charAt
value        = myMap.get("25") ;     // method get
myArray[25]  = value ;               // subscript operator
myVector.set(25, value) ;            // method set
myMap.put("25", value) ;             // method put

Java에서 각 컨테이너가 동일한 작업 (인덱스 또는 식별자를 통해 내용에 액세스)을 수행하는 방법이 다르다는 것을 알 수 있습니다. 이는 다른 방법으로 혼란을 일으 킵니다.

C++에서 각 컨테이너는 연산자 오버로딩을 통해 동일한 방식으로 내용에 액세스합니다.

자연 고급 유형 조작

아래 예제는 Google에서 " Java Matrix object "및 " c ++ Matrix object "에 대한 첫 번째 링크를 사용하여 찾은 Matrix객체를 사용합니다.

// C++ YMatrix matrix implementation on CodeProject
// http://www.codeproject.com/KB/architecture/ymatrix.aspx
// A, B, C, D, E, F are Matrix objects;
E =  A * (B / 2) ;
E += (A - B) * (C + D) ;
F =  E ;                  // deep copy of the matrix

// Java JAMA matrix implementation (seriously...)
// http://math.nist.gov/javanumerics/jama/doc/
// A, B, C, D, E, F are Matrix objects;
E = A.times(B.times(0.5)) ;
E.plusEquals(A.minus(B).times(C.plus(D))) ;
F = E.copy() ;            // deep copy of the matrix

그리고 이것은 행렬에만 국한되지 않습니다. Java의 BigIntegerBigDecimal클래스는 동일한 혼란스러운 자세한 표시를 사용하지만 C++의 해당 클래스는 기본 제공 유형만큼 명확합니다.

자연적 반복자 :

// C++ Random Access iterators
++it ;                  // move to the next item
--it ;                  // move to the previous item
it += 5 ;               // move to the next 5th item (random access)
value = *it ;           // gets the value of the current item
*it = 3.1415 ;          // sets the value 3.1415 to the current item
(*it).foo() ;           // call method foo() of the current item

// Java ListIterator<E> "bi-directional" iterators
value = it.next() ;     // move to the next item & return the value
value = it.previous() ; // move to the previous item & return the value
it.set(3.1415) ;        // sets the value 3.1415 to the current item

자연 펑터 :

// C++ Functors
myFunctorObject("Hello World", 42) ;

// Java Functors ???
myFunctorObject.execute("Hello World", 42) ;

텍스트 연결 :

// C++ stream handling (with the << operator)
                    stringStream   << "Hello " << 25 << " World" ;
                    fileStream     << "Hello " << 25 << " World" ;
                    outputStream   << "Hello " << 25 << " World" ;
                    networkStream  << "Hello " << 25 << " World" ;
anythingThatOverloadsShiftOperator << "Hello " << 25 << " World" ;

// Java concatenation
myStringBuffer.append("Hello ").append(25).append(" World") ;

좋아, Java에서 MyString = "Hello " + 25 + " World" ;도 사용할 수 있습니다 ...하지만 잠깐 기다려주세요 : 이것은 연산자 오버로딩입니까, 그렇지 않습니까? 속이는 거 아닌가 ??? ???

:-디

일반 코드?

동일한 일반 코드 수정 피연산자는 내장/기본 (Java에서 인터페이스가 없음), 표준 객체 (올바른 인터페이스를 가질 수 없었 음) 및 사용자 정의 객체 모두에 사용할 수 있어야합니다.

예를 들어, 임의의 유형의 두 값의 평균값 계산 :

// C++ primitive/advanced types
template<typename T>
T getAverage(const T & p_lhs, const T & p_rhs)
{
   return (p_lhs + p_rhs) / 2 ;
}

int     intValue     = getAverage(25, 42) ;
double  doubleValue  = getAverage(25.25, 42.42) ;
complex complexValue = getAverage(cA, cB) ; // cA, cB are complex
Matrix  matrixValue  = getAverage(mA, mB) ; // mA, mB are Matrix

// Java primitive/advanced types
// It won't really work in Java, even with generics. Sorry.

연산자 오버로딩에 대한 논의

연산자 오버로딩을 사용하는 C++ 코드와 Java에서 동일한 코드를 공정한 비교를 통해 살펴 보았으므로 "연산자 오버로딩"을 개념으로 논의 할 수 있습니다.

운영자 과부하는 컴퓨터가 있기 전부터 존재합니다.

컴퓨터 과학 밖에서도 연산자 오버로딩이 있습니다. 예를 들어, 수학에서 +, -, * 등과 같은 연산자는 오버로드됩니다.

실제로, +, -, * 등의 의미는 피연산자의 유형 (수치, 벡터, 양자 파 함수, 행렬 등)에 따라 달라집니다.

과학 수업의 일환으로 우리 대부분은 피연산자 유형에 따라 연산자에 대한 여러 가지 의미를 배웠습니다. 우리가 그들을 혼란스럽게 만들었나요?

연산자 오버로딩은 피연산자에 따라 다릅니다.

이것은 연산자 오버로딩에서 가장 중요한 부분입니다 : 수학이나 물리학에서와 마찬가지로 연산은 피연산자 유형에 따라 다릅니다.

따라서 피연산자의 유형을 알고 작업의 효과를 알 수 있습니다.

심지어 C와 Java는 (하드 코딩 된) 연산자 오버로딩을 가지고 있습니다.

C에서는 연산자의 실제 동작이 피연산자에 따라 변경됩니다. 예를 들어, 두 개의 정수를 더하는 것은 두 개의 복식을 추가하는 것과는 다르며, 정수 하나와 두 개의 정수를 더하는 것과는 다릅니다. 심지어 모든 포인터 산술 도메인이 있습니다 (캐스팅하지 않고 포인터에 정수를 추가 할 수 있지만 두 포인터를 추가 할 수는 없습니다 ...).

Java에서 포인터 연산은 없지만 + 연산자가없는 문자열 연결이 여전히 발견되면 "연산자 오버로딩은 악의적 인"신조에서 예외를 정당화 할만큼 충분히 우스꽝 스럽습니다.

그것은 C (역사적 이유로) 또는 Java (for 개인적인 사유, 아래 참조) 코더, 당신은 자신의 것을 제공 할 수 없습니다.

C++에서 연산자 오버로딩은 선택 사항이 아닙니다 ...

C++에서, 내장형에 대한 연산자 오버로딩은 불가능합니다 (그리고 이것은 좋은 일입니다). 사용자 정의 유형에는 사용자 정의 연산자 오버로드.

이미 이전에 언급했듯이, C++과 자바와 달리 사용자 유형은 빌트인 유형과 비교했을 때 언어의 2 등 시민으로 간주되지 않습니다. 따라서 기본 제공 유형에 연산자가있는 경우 사용자 유형에서도 연산자를 사용할 수 있어야합니다.

사실은 toString(), clone(), equals() 메소드는 Java (즉 준 표준형), C++ 연산자 오버로딩은 C++의 상당 부분이므로 원래 C 연산자 나 앞서 언급 한 Java 메소드만큼 자연 스럽습니다.

템플릿 프로그래밍과 결합하여 연산자 오버로딩은 잘 알려진 디자인 패턴이됩니다. 사실 과부하 연산자를 사용하지 않고 STL에서 멀리 갈 수없고 자신의 클래스에 연산자를 오버로드 할 수 없습니다.

...하지만 학대 받아서는 안됩니다.

연산자 오버로딩은 연산자의 의미를 존중하도록 노력해야합니다. "add함수에서 빼기"또는 "clone메서드에서 쓰레기를 반환"처럼 + 연산자에서 빼기를 수행하지 마십시오.

캐스트 오버로드는 모호함으로 이어질 수 있으므로 매우 위험 할 수 있습니다. 그래서 그들은 명확하게 정의 된 경우를 위해 예약되어야합니다. &&||는 네이티브 운영자 &&||가 누리는 단락 회로 평가를 잃어 버리기 때문에 실제로 수행중인 작업을 알지 못하면 오버로드하지 마십시오.

그래서 ... Ok ... 그럼 왜 Java에서는 불가능합니까?

James Gosling이 그렇게 말했기 때문에 :

나는 연산자 오버로딩을 생략했다. 상당히 개인적인 선택 너무 많은 사람들이 C++에서 악용하는 것을 보았 기 때문에.

제임스 고슬링. 출처 : http://www.gotw.ca/publications/c_family_interview.htm

위의 Gosling의 텍스트를 Stroustrup과 비교해보십시오.

많은 C++ 디자인 결정은 사람들로 하여금 특정 방식으로 일을하도록 강제하는 것에 대한 나의 싫어함에 뿌리를두고 있습니다. [...] 나는 개인적으로 싫어하는 특징을 무법화하려는 유혹에 시달렸 기 때문에 그렇게하지 않았습니다. 나는 다른 사람들에 대한 내 견해를 강요 할 권리가 있다고 생각하지 않았다..

Bjarne Stroustrup. 출처 : C++의 발전과 진화 (1.3 일반 배경)

연산자 오버로딩이 자바에 도움이 될까요?

어떤 객체는 연산자 오버로딩 (BigDecimal, 복소수, 행렬, 컨테이너, 반복기, 비교 자, 파서 등의 구체적인 또는 숫자 유형)의 이점을 크게 누릴 수 있습니다.

C++에서는 Stroustrup의 겸손으로이 이익에서 이익을 얻을 수 있습니다. Java에서는 Gosling의 이유로 인해 개인적인 선택.

Java에 추가 될 수 있습니까?

자바에서 연산자 오버로딩을 추가하지 않은 이유는 내부 정치, 기능에 대한 알레르기, 개발자의 불신 (당신이 알기 론, 자바 팀을 따라 잡는 것 같은 사보타지), 이전 JVM과의 호환성, 올바른 사양 등을 쓸 시간.

그러니이 기능을 기다리는 숨을 멈추지 마십시오 ...

하지만 그들은 C #에서 그것을 할!

네...

이 두 언어의 유일한 차이점은 아니지만이 언어는 나를 즐겁게하지 못합니다.

분명히, C # 사람들은 "모든 프리미티브는 structname__이고 structname__은 Object에서 파생됩니다"처음 시도 할 때 제대로 했어.

그리고 그들은 그것을합니다 다른 언어들 !!!

사용 된 정의 연산자 오버로딩에 대한 모든 FUD에도 불구하고 다음과 같은 언어가 지원됩니다. Scala , Dart , Python , F # =, C # , D , ALGOL 68 , Smalltalk , Groovy , Perl 6 , C++, Ruby , Haskell , MATLAB , Eiffel , Lua , Clojure , Fortran 9 , Swift , Ada , Delphi 2005 ...

너무나 많은 언어들, 매우 다양한 (때로는 반대되는) 철학들이 있습니다. 그러나 그들은 모두 그 점에 동의합니다.

생각할 거리...

753
paercebal

James Gosling은 Java 설계를 다음과 같이 비유했습니다.

"한 아파트에서 다른 아파트로 이사 할 때 이동하는 것에 대한 원칙이 있습니다 흥미로운 실험은 아파트를 포장하고 모든 것을 상자에 넣은 다음 다음 아파트로 이사하고 필요한 때까지는 포장을 풀지 않는 것입니다. 첫 식사를 다시하고 상자에서 물건을 꺼내는 것입니다. 그런 다음 한 달이 지나면 실제로 필요한 것들을 실제로 파악할 수 있습니다. 물건 - 당신이 그것을 얼마나 좋아하는지, 얼마나 차가운 지 잊어 버리고 그냥 던져 버리십시오. 당신의 삶을 단순화시키는 방법이 놀랍습니다. 모든 종류의 디자인 문제에서 그 원칙을 사용할 수 있습니다. 차가워 지거나 흥미 롭기 때문에. "

여기서 인용문의 문맥

기본적으로 연산자 오버로딩은 일종의 포인트, 통화 또는 복소수를 모델링하는 클래스에 유용합니다. 그러나 그 후에는 예제를 빨리 빠지기 시작합니다.

또 다른 요소는 개발자가 '&&', '||', 캐스트 연산자 및 물론 'new'와 같은 연산자를 오버로드하는 C++의 기능 남용입니다. 이것을 값과 예외를 합친 결과로 생기는 복잡성은 Exceptional C++ 책에 잘 설명되어 있습니다.

42
Garth Gilmour

Boost.Units : 링크 텍스트 를 확인하십시오.

연산자 오버로딩을 통해 제로 오버 헤드 차원 분석을 제공합니다. 얼마나 더 명확 해 질 수 있습니까?

quantity<force>     F = 2.0*newton;
quantity<length>    dx = 2.0*meter;
quantity<energy>    E = F * dx;
std::cout << "Energy = " << E << endl;

실제로 "Energy = 4 J"를 출력합니다.

22
user15793

자바 설계자는 운영자 과부하가 가치가있는 것보다 더 많은 문제가 있다고 판단했습니다. 그처럼 간단합니다.

모든 객체 변수가 실제로 참조 인 언어에서 연산자 오버로딩은 C + + 프로그래머에게는 매우 비논리적이라는 추가적인 위험을 초래합니다. 상황을 C #의 연산자 == 연산자 오버로딩과 Object.EqualsObject.ReferenceEquals (또는 무엇이든간에) 비교하십시오.

11
Sebastian Redl

Groovy 연산자 오버로드가 있고 JVM에서 실행됩니다. 실적에 영향을주지 않으면 (매일 더 적음) 메소드 이름에 따라 자동으로 실행됩니다. 예 : '+'는 '더하기 (인수)'메소드를 호출합니다.

8
noah

이것은 개발자가 자신의 이름이 명확하게 의도를 전달하는 함수를 작성하도록하는 의식적인 디자인 선택 일 수 있다고 생각합니다. C++에서 개발자는 주어진 연산자의 일반적으로 받아 들여지는 속성과 관계가없는 기능을 연산자에 과부하하게되어 연산자 정의를 보지 않고 코드의 기능을 결정하는 것을 거의 불가능하게 만듭니다.

6
user14128

운전자 과부하로 발을 쏠 수 있습니다. 그것은 포인터와 마찬가지로 사람들은 그들과 어리석은 실수를 짓기 때문에 가위를 없애기로 결정했습니다.

적어도 그것이 그 이유라고 생각합니다. 어쨌든 난 네 편이야. :)

5
Sarien

어떤 사람들은 Java에서 연산자 오버로딩이 obsfuscation으로 이어질 것이라고 말합니다. 사람들이 BigDecimal을 사용하여 일정 비율로 재정적 가치를 높이는 것과 같은 기본적인 수학을하는 Java 코드를 보려고 멈추었습니까? .... 그러한 운동의 자세한 표시는 obsfuscation의 자체 데모가됩니다. 아이러니 컬하게도, 연산자 오버로딩을 Java에 추가하면 우리는 Currency 클래스를 만들 수 있습니다.이 클래스는 이러한 수학적 코드를 우아하고 단순하게 만듭니다 (obsfuscated).

4
Volksman

엄밀히 말하자면, 다양한 프로그래밍 언어에서 연산자가 오버로드되어 다른 유형의 숫자를 처리 할 수 ​​있습니다. 정수 및 실수. 설명 : 용어 오버로드 란 하나의 기능에 대해 단순히 여러 가지 구현이 있음을 의미합니다. 대부분의 프로그래밍 언어에서 연산자 +, 정수, 실수에 대해 서로 다른 구현이 제공됩니다.이를 연산자 오버로딩이라고합니다.

이제는 많은 사람들이 Java가 연산자에 대해 연산자 오버로드를하고 문자열을 함께 추가하는 것이 이상하다는 것을 알았습니다. 수학적 관점에서 보았을 때 실제로 이상하게 들릴 수도 있지만 프로그래밍 언어의 개발자 관점에서 보면 내장 연산자 오버로딩을 추가하는 데는 아무런 문제가 없습니다 연산자의 경우 + 다른 클래스의 경우 끈. 그러나 대부분의 사람들은 일단 String을위한 내장 오버로딩을 추가하면 일반적으로 개발자를 위해이 기능을 제공하는 것이 좋습니다.

개발자가 결정할 수 있으므로 코드 오버플로가 과장되는 오류와 완전히 반대됩니다. 이것은 생각하기에 순진하고, 아주 정직하기 위하여, 그것은 오래되게되고있다.

+1 Java 8에서 연산자 오버로딩을 추가합니다.

4
Olai

해당 연산자 오버로드로 인해 운영자가 연산 논리와 일치하지 않는 유형의 논리적 오류가 발생한다고 말하는 것은 아무 의미도없는 것과 같습니다. 함수 이름이 연산 논리에 부적합하다면 같은 유형의 오류가 발생합니다. 해결책은 무엇입니까? 함수 사용 기능을 떨어 뜨리십시오! 이것은 코믹한 대답입니다 - "부적절한 연산 로직", 모든 매개 변수 이름, 모든 클래스, 함수 또는 논리적으로 부적절한 것일 수 있습니다. 이 옵션은 존경할만한 프로그래밍 언어에서 사용할 수 있어야하며 안전하지 않다고 생각하는 사용자는 사용하지 않으면 안된다고 말합니다. C #을 가져 가자. 그들은 포인터를 떨어 뜨 렸지만 헤이 - 당신이 위험 부담을 감수하면서 '안전하지 않은 코드'선언문 프로그램이 있습니다.

4
Kvant

Java를 구현 언어로 가정하면 a, b 및 c는 모두 초기 값이 null 인 Complex를 참조하는 것입니다. 또한 Complex가 언급 된 BigInteger 및 이와 유사한 불변 BigDecimal 으로 변경되지 않는다고 가정하면 다음과 같은 의미로 생각할 수 있습니다. 당신은 b와 c를 더하여 반환 된 컴플렉스에 대한 참조를 할당하고이 참조를 a와 비교하지 않습니다.

그렇지 않습니다 :

Complex a, b, c; a = b + c;

훨씬 간단하다 :

Complex a, b, c; a = b.add(c);
2
David Schlosnagle

가끔 연산자 오버로딩, 친구 클래스 및 다중 상속을 갖는 것이 좋습니다.

그러나 나는 여전히 그것이 좋은 결정이라고 생각한다. Java에 연산자 오버로딩이 있었다면 소스 코드를 보지 않고도 연산자의 의미를 확신 할 수 없었습니다. 현재 그럴 필요는 없습니다. 그리고 연산자 오버로딩 대신 메서드를 사용하는 예제도 꽤 읽기 쉽다고 생각합니다. 일을 더 분명하게하고 싶다면 항상 털이있는 문장 위에 주석을 추가 할 수 있습니다.

// a = b + c
Complex a, b, c; a = b.add(c);
1
user14070

Java 운영자 과부하에 대한 기본 지원의 대안

Java에는 연산자 오버로딩이 없으므로 다음과 같은 몇 가지 대안을 살펴볼 수 있습니다.

  1. 다른 언어를 사용하십시오. GroovyScala 연산자 오버로드가 있으며 자바를 기반으로합니다.
  2. 자바에서 연산자 오버로딩을 가능하게하는 Java-oo 플러그인을 사용하십시오. 그것은 플랫폼에 독립적이 아닙니다. 또한 많은 문제가 있으며 최신 Java 릴리스 (예 : Java 10)와 호환되지 않습니다. ( 원본 StackOverflow 소스 )
  3. JNI , Java Native Interface 또는 대안을 사용하십시오. 이것은 Java에서 사용하기 위해 C 또는 C++ (아마도 다른 것?) 메소드를 작성할 수있게합니다. 물론 이것은 플랫폼에 독립적이지 않습니다.

누군가 다른 사람을 알고 있으면 의견을 말하고, 나는이 목록에 추가 할 것입니다.

0
gagarwa

이것은 이것을 허용하지 않는 좋은 이유는 아니지만 실용적인 이유입니다.

사람들은 항상 책임감있게 사용하지 않습니다. 이 예제를 파이썬 라이브러리 scapy에서 보자.

>>> IP()
<IP |>
>>> IP()/TCP()
<IP frag=0 proto=TCP |<TCP |>>
>>> Ether()/IP()/TCP()
<Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>>
>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
<IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/IP()/UDP()
<Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>>
>>> IP(proto=55)/TCP()
<IP frag=0 proto=55 |<TCP |>>

여기에 설명이 있습니다.

/ 연산자는 두 레이어 사이의 컴포지션 연산자로 사용되었습니다. 그렇게 할 때, 하위 계층은 상위 계층에 따라 과부하 된 하나 이상의 기본 필드를 가질 수 있습니다. (당신은 여전히 ​​당신이 원하는 가치를 줄 수 있습니다). 문자열은 원본 레이어로 사용할 수 있습니다.

0
Sarien