当前位置:  开发笔记 > 编程语言 > 正文

为什么Java不提供运算符重载?

如何解决《为什么Java不提供运算符重载?》经验,为你挑选了9个好方法。

从C++到Java,明显没有答案的问题是为什么Java不包含运算符重载?

是不是Complex a, b, c; a = b + c;比简单得多Complex a, b, c; a = b.add(c);

是否存在已知的原因,有效的论据,使运算符重载?这个理由是武断的,还是输给了时间?



1> paercebal..:

有很多帖子抱怨运营商超载.

我觉得我必须澄清"操作员重载"的概念,为这个概念提供另一种观点.

代码混淆?

这种说法是一种谬误.

所有语言都可以进行混淆......

通过函数/方法对C或Java中的代码进行模糊处理与在C++中通过运算符重载一样容易:

// 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中的Cloneable接口:

您应该克隆实现此接口的对象.但你可以说谎.并创建一个不同的对象.实际上,这个界面非常弱,你可以完全返回另一种类型的对象,只是为了它的乐趣:

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

由于Cloneable接口可能被滥用/混淆,是否应该以相同的理由禁止C++运算符重载?

我们可以重载类的toString()方法,MyComplexNumber让它返回当天的字符串化小时.是否应该toString()禁止超载?我们可以破坏MyComplexNumber.equals它返回一个随机值,修改操作数......等等.

在Java中,如在C++或任何语言中,程序员在编写代码时必须遵守最少的语义.这意味着实现一个add添加的函数,Cloneable克隆的实现方法和一个++运算符而不是递增.

什么是混淆?

现在我们知道即使通过原始的Java方法也可以破坏代码,我们可以问自己C++中运算符重载的真正用法吗?

清晰自然的表示法:方法与运算符重载?

对于不同的情况,我们将在下面比较Java和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++中的任何类型.在Java中,当A和B不是原语时,代码可能变得非常混乱,即使对于类似原始的对象(BigInteger等)......

自然数组/容器访问器和下标:

// 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++中,由于运算符重载,每个容器使用相同的方式来访问其内容.

自然先进的类型操纵

下面的示例使用一个Matrix对象,使用Google上的第一个链接找到" Java Matrix对象 "和" c ++ 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

而且这不仅限于矩阵.该BigIntegerBigDecimal的Java类来自同一个混乱的冗长痛苦,而他们在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 "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" ;......但是,等一下:这是运算符重载,不是吗?是不是在作弊?

:-D

通用代码?

修改操作数的相同通用代码应该可用于内置插件/基元(Java中没有接口),标准对象(无法使用正确的接口)和用户定义的对象.

例如,计算任意类型的两个值的平均值:

// C++ primitive/advanced types
template
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(由于个人原因,见下文)编码器,你不能提供自己的.

在C++中,运算符重载不是可选的......

在C++中,内置类型的运算符重载是不可能的(这是一件好事),但用户定义的类型可能具有用户定义的运算符重载.

如前所述,在C++中,与Java相反,与内置类型相比,用户类型不被视为该语言的二等公民.因此,如果内置类型具有运算符,则用户类型也应该能够拥有它们.

事实是,像toString(),clone(),equals()方法是对Java(即准标准样),C++运算符重载是C的这么多的部分++,它变得一样自然原来的C经营者,或之前提到的Java方法.

结合模板编程,操作符重载成为众所周知的设计模式.实际上,如果不使用重载运算符,并且为自己的类重载运算符,则无法在STL中走得很远.

......但它不应该被滥用

运算符重载应该努力尊重运算符的语义.不要在+运算符中减去(如"不在add函数中减去"或"在clone方法中返回垃圾").

转换重载可能非常危险,因为它们可能导致含糊不清.因此,它们应该被保留用于明确定义的案例.至于&&||,永远不要超载它们,除非你真的知道自己在做什么,因为你会失去短路评价的本土运营商&&||享受.

那么......好吧......那么为什么Java不可能呢?

因为詹姆斯·高斯林这么说:

我遗漏了操作符重载作为一个相当个人的选择,因为我看到有太多人在C++中滥用它.

詹姆斯戈斯林.资料来源:http://www.gotw.ca/publications/c_family_interview.htm

请将Gosling上面的文字与下面的Stroustrup进行比较:

许多C++设计决策源于我不喜欢强迫人们以某种​​特定方式做事[...]通常,我很想禁止我个人不喜欢的功能,我没有这样做因为我认为我没有这样做强迫我对别人的看法的权利.

Bjarne Stroustrup.资料来源:C++的设计和演变(1.3一般背景)

运算符重载会使Java受益吗?

一些对象将极大地受益于运算符重载(具体或数字类型,如BigDecimal,复数,矩阵,容器,迭代器,比较器,解析器等).

在C++中,由于Stroustrup的谦逊,你可以从这个好处中获益.在Java中,由于Gosling的个人选择,你只是被搞砸了.

它可以添加到Java吗?

现在不在Java中添加运算符重载的原因可能是内部政治,对功能的过敏,开发人员的不信任(你知道,似乎困扰Java团队的破坏者......),与以前的JVM的兼容性,是时候写一个正确的规格等了.

所以不要屏住呼吸等待这个功能......

但是他们在C#中做到了!

是啊...

虽然这远不是​​两种语言之间的唯一区别,但这一点永远不会让我高兴.

显然,C#伙伴们,他们的"每一个原语都是一个struct,而一个struct派生自对象",在第一次尝试时就做对了.

他们用其他语言做!

尽管所有FUD都反对使用定义的运算符重载,但以下语言支持它:Scala,Dart,Python,F#,C#,D,Algol 68,Smalltalk,Groovy,Perl 6,C++,Ruby,Haskell,MATLAB,Eiffel,Lua,Clojure,Fortran 90,Swift,Ada,Delphi 2005 ......

如此多的语言,有许多不同的(有时是对立的)哲学,但他们都同意这一点.

值得思考的东西......


,见下文)编码器,你不能提供自己的.
类型可能具有
运算符重载.
),C++运算符重载是C的这么多的部分++,它变得一样自然原来的C经营者,或之前提到的Java方法.


,你只是被搞砸了.
,在第一次尝试时就做对了.
史诗般的答案.我读过的最合格的揭穿之一.
@Douglas Leeder:谢谢!运算符重载就像OOP.你第一次学会这样做,你可以在任何地方编写重载,因为你可以在任何地方放置基类和继承(例如,甜美的讽刺,Java API).但是这种传递速度非常快,然后你就会意识到这种可能性并没有滥用它.我自己10年以上的C++经验是,我在代码和其他编码器的代码中看到的不良重载次数都很低,我相信我一方面可以算数.这比使用sprintf,strcat,memset和缓冲区溢出的整体错误数量要少得多.
这是一个很好的答案.我不同意它,但它仍然是一个很好的答案.我认为过载不良可能带来的问题超过了良好过载的价值.
@Douglas Leeder:我相信,在另一个SO问题中讨论过这个问题之后,运营商超载的"爱好者"和"仇恨者"之间的差距可能是由于他们的代码方法不同造成的:"仇恨者"更多是"功能"重要的是",意味着他们希望功能只做一件事,而且只做一件事.因此,操作员应按照语言设计工作."恋人"更多地是关于"对象应该表现",这意味着他们更容易接受该功能(因此,操作员)可以根据其参数的类型改变他们的行为.
@MaartenBodewes:我上面写的所有例子,以及困扰你的一切都是*"作为开发人员,你因为Gosling的个人选择而被搞砸了"*?请写下你自己的答案,捍卫*"你的开发人员是愚蠢的,让天才人为你决定你需要什么"*角度.这个讨论没有任何意义.
@phresnel:感谢"Epic回答"评论!
@Sokwhan Huh:"我真的很生气,提问者没有选择这个回答作为公认的答案."实际上有一个金徽章,可以获得接受答案两倍积分的答案:http://stackoverflow.com/badges/ 62 /民粹主义者...... ^ _ ^
@ user7610:两篇论文(只有两页?)是提供技术示例和演示,可以启动技术讨论,并且可以达成合理的技术决策.这里的关键词是"技术性的"......虽然答案有点脱离背景,但它提供的东西比简单的引语更好(这与SO我认为无关),即对感知问题的分析.我想收到的压倒性票数(正面和负面)和评论显示这个答案作为一个整体被发现比复制粘贴报价更有趣.
@MaartenBodewes除了Gosling的"味觉决定"学校之外,还有Stroustrup的学校"通过考虑你的经验和其他专家的经验来决定,包括那些不同意你的人".我倾向于支持最后一所学校.此外,运算符重载不是技术挑战,理解/同化也不复杂,正如无数其他语言(包括Java的双胞胎,C#)所证明的那样.运算符重载只是一些错误的方式.太糟糕了,因为正如我演示的那样,它可以使代码更清晰.
这可能会导致记录最长的记录回复时间:-)
@Hassan:单行注释(// ...)在C IIRC中起作用,单行注释在C99中起作用,而不在C89中起作用。
@ user1216838:就像在数学或量子物理学中一样,运算符依赖于上下文.在C++中,对于仿函数使用"<<"表示"()"流是很自然的,没有C++开发人员会反对它们.现在,来C++的C(或Java)开发人员会感到惊讶,但是,嘿,你正在学习一门新语言.那么你应该期望学习新的方法.对于"append()",它是如此自然,他们决定反对它的Java字符串,而是重载"+"和"+ ="...... :-)
@ user1216838:`为了更详细和更明确的含义语法的好处:这是一个明显的矛盾.矩阵是这里最好的例子.看看数学和物理学中的实际符号,你会发现**无处不在**他们使用的符号类似于Java的符号,而且确实,他们的符号类似于C++的符号.仅这一点就证明了清晰和冗长不会在一起.你在争论的是你自己的编码习惯以及使用运算符重载的不情愿.C++开发人员(实际上,其他语言开发人员)没有相同的限制.
我不敢相信,经过这样一个干净的逻辑回答,人们仍然无法得到OP的观点!并且争论琐碎的事情,例如"<<"是否令人困惑.它与OP的推理无关.关键是你不要禁止某些功能只是因为有些人会滥用它,一切都可能被滥用.如果用刀切肉,如果有人用它来杀人,你是否决定让所有的刀变钝,这样无聊甚至不会切水果?
@MaartenBodewes:开发人员的期望取决于语言.在C++中,没有开发人员期望a + b可以调用内置`operator +`.相反,他们希望调用正确的`operator +`.事实上,C和Java开发人员对内置运算符有这样的期望是因为他们对语言的局限性有所了解.然后,出于某种原因,尽管所有其他语言都证明不是这样,但是由于限制而产生的这种期望被提升为他们不能没有的东西.戈斯林的决定是个人品味的问题.

2> Garth Gilmou..:

James Gosling将Java设计为以下内容:

"当你从一个公寓搬到另一个公寓时,有一个关于移动的原则.一个有趣的实验是打包你的公寓,把所有东西放在盒子里,然后进入下一个公寓,不要打开任何东西直到你需要它.所以你'重新开始你的第一顿饭,然后你从盒子里拿出一些东西.然后在一个月左右之后你就用它来弄清楚你生活中你真正需要的东西,然后你拿走其余的东西.东西 - 忘记你喜欢多少或多酷 - 你只是扔掉它.令人惊讶的是它如何简化你的生活,你可以在各种设计问题中使用这个原则:不要仅仅因为他们做事情"很酷或只是因为他们很有趣."

您可以在此处阅读报价的上下文

基本上,运算符重载对于模拟某种点,货币或复数的类非常有用.但在那之后你开始快速耗尽示例.

另一个因素是开发人员重载运算符滥用C++中的功能,例如'&&','||',强制转换操作符,当然还有'new'.Exceptional C++一书中详细介绍了将其与值和异常传递相结合所带来的复杂性.


对詹姆斯·戈斯林有用的东西并不适用于所有人.他推断他的"有趣"包装实验意味着"抛弃我不需要的世界上的一切,所以没有人可以使用那些东西." 他显然不知道我需要或使用什么.
@BT:与Stroustrup在这个问题上的观点相比,最令人高兴的是Gosling的观点:"许多C++设计决定源于我不喜欢强迫人们以某种​​特定方式做事[...]通常,我很想禁止我个人不喜欢的一个功能,我没有这样做,因为我不认为我有权强迫我对别人的看法.(B. Stroustrup)`.
@Software Monkey:"C++,广受谴责,另一个,Java,广受欢迎"这是营销炒作.请记住,C++是独自成长的,而Java(和.NET)则从营销推土机中获益.对于"广受欢迎的语言",Java仅限于服务器应用程序,而"受到广泛谴责"(可能是希望降低代码生成成本的Java开发人员和管理人员),C++似乎非常高 - 性能服务器到高性能游戏?[...]
@Hassan:每种语言都有它的黑客,Java的泛型就是一个很好的例子.现在,关于`我希望他们去看看那里的一些C++代码,这些代码与奇怪的黑客和语言的"特殊"特征一起被隐藏起来:糟糕的程序员将编写错误的代码,无论语言如何.只是尝试在Java中模拟函数参数的"pass-by-reference"以获得一个想法.我看过这些代码,并且笑得很厉害.这是Gosling没有使用的东西,因此,在Java中需要可怕的黑客,然而,在C#和C++中本地存在,零成本.
你能提供一个代码示例"运算符重载的复杂性与传值和异常相结合"吗?尽管用了几年的语言,拥有并阅读了所有关于C++的有效/特殊书籍,但我无法理解你的意思.
"基本上,运算符重载对于模拟某种点,货币或复数的类很有用.但之后你就开始快速耗尽示例." 日期怎么样?或Java设计师从未想过的数十种可订购数据类型之一?
@Paercebal:"最具启发性的是Gosling的......与Stroustrup相比".有意思,但我会主观地认为,差异导致了一种语言,C++,广泛受到谴责,而另一种语言,Java,广受欢迎.或许专家们可以说"这是一个糟糕的想法".
@Software Monkey:[...]我自己在Java/.NET和C++之间的比较对Java/.NET不太有利.总结一下:在Java/.NET中生成平均质量代码比在C++中更容易,更快,但是当您需要优秀到完美的高性能质量代码时,Java/.NET将阻碍您,而C++将使您很容易 有关这方面的更多信息,请参阅我的回答:http://stackoverflow.com/questions/145110/c-performance-vs-java-c/145559#145559
“基本上,运算符重载对于对某种点,货币或复数建模的类非常有用。但是之后,您很快就会用尽示例。” 您想对I / O进行排序的任何数据类型如何?Java的I / O例程非常难看,尤其是在抽象层和数据库层中。此外,您要访问第N个项或进行某种键-值映射的任何容器类都可以很好地利用运算符重载。没有运算符重载或没有默认参数值,我感到惊讶的是有人使用了这种语言,尤其是拥有Oracle的这种语言。
关于Java的许多事情源于Gosling的个人观念,这可能并不总是与现实相符.他拒绝提供无符号的`byte`类型,声称无符号类型会导致问题,而实际上唯一导致问题的无符号类型是*大于默认促销类型*(当然,`Byte`类型)不会;我认为任何Pascal程序员都不会遇到"Byte"签名的麻烦.但是,关于运算符重载,我认为像Java这样的基于引用的OOP语言有一个引用比较运算符是很重要的.
出于同样的原因,Gosling还忽略了函数指针,看看我们今天的位置...

3> 小智..:

查看Boost.Units:链接文本

它通过运算符重载提供零开销的维度分析.这会更清楚多少?

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

实际上会输出"Energy = 4 J",这是正确的.



4> Aaron..:

假设您想要覆盖引用的对象的先前值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现在指的是相同的值.结果,比较将产生"相等",因为对象将比较自身.

副本和引用之间的差异只会增加操作符重载的混乱.正如@Sebastian所提到的,Java和C#都必须分别处理值和引用相等 - operator+可能会处理值和对象,但是operator=已经实现了处理引用.

在C++中,您应该一次只处理一种比较,因此可以减少混淆.例如,打开Complex,operator=并且operator==都在处理值 - 分别复制值和比较值.


这个答案根本没有回答这个问题.你只是在利用java对等号的使用.如果b + C返回一个新的Complex,那么a = b + c将是完全有效的,并且更容易阅读.即使你想修改一个原样,a.set(b + c)也比较容易阅读 - 特别是当算术不仅仅是微不足道的时候:a.set((a*b + b*c)/ 5 )或a = a.multiply(b).add(b.multiply(c)).divide(5).你的选择..
或者我猜......不是你的选择,视情况而定
这不是问题的答案.这是某人对Java和C++之间某些差异的猜测.
在C++中,表达式模板解决了额外副本的问题.几乎所有主要的算术库都使用这种技术就是出于这个原因.此外,这并没有解决这个问题,因为a = b + c只是a.foo(b.bar(c))的语法糖,这实际上是问题中的初始观察.
这真的很简单......就像Python一样,没有重载的任务.

5> Sebastian Re..:

Java设计者认为运算符重载比它的价值更麻烦.就那么简单.

在一种语言中,每个对象变量实际上都是一个引用,运算符重载会带来额外的不合逻辑的危险 - 至少对C++程序员来说.将情况与C#的==运算符重载Object.EqualsObject.ReferenceEquals(以及它所谓的)进行比较.



6> noah..:

Groovy有运算符重载,并在JVM中运行.如果你不介意性能损失(每天变小).它是基于方法名称自动完成的.例如,'+'调用'plus(argument)'方法.


我希望所有带有运算符重载的语法繁重的语言都会使用该技术.我永远不明白为什么他们必须发明一个特殊版本的方法命名和查找.Stroustrup在D&EC++中没有提到任何替代方案.C#团队使用Linq语法采用了正确的方法(`where``变成`.Where(i => ...`).如果只是他们对算术运算符做了同样的事情,那么很多东西会更简单更强大.Java具有干净的优势,可以做到这一点(尽管出于宗教原因,它可能永远不会).

7> user14128..:

我认为这可能是一种有意识的设计选择,迫使开发人员创建名称清楚地传达其意图的功能.在C++中,开发人员会使运算符过载,这些功能通常与给定运算符的普遍接受性质无关,这使得在不查看运算符定义的情况下几乎无法确定代码片段的作用.


`在C++中,开发人员会使运算符重载,这些功能通常与给定运算符的普遍接受的性质无关:这是一个无偿的断言.我从12年开始就是一名专业的C++开发人员,我很少遇到这个问题.事实上,我在C++中看到的最多的错误和设计错误都是在C风格的代码中(`void*`,casts等)
-1.您指定的每个变量都是符号,就像算术运算符符号一样.您是否使用短语来命名该变量,单个单词或单个字母,是您(或您的团队)的决定.谁说什么是有意义的,什么不是?答案是你,程序员.在纯数学中,矩阵之间的乘法意味着在基本算术中两个数之间的乘法不同.然而,我们对两种类型的乘法都使用相同的符号.
@BenVoigt:[...]我甚至没有提到`add`函数可能真的被误用(比如做乘法,或者获取互斥)... user14128提到的滥用不仅限于操作员,但是有一些关于运算符重载的病态恐惧,我相信它来自C与C++的早期阶段,这种恐惧未经修改直接进入Java,但幸运的是,没有进入C#...最后尊重语义和编写清晰的函数/运算符是开发人员的工作.不是语言.
@paercebal:不幸的是,断言是正确的.你必须看起来不比IOstreams更能看到它的实际效果.值得庆幸的是,大多数开发人员对于为现有运营商发明新语义更为谨慎.

8> Sarien..:

那么你可以通过操作员超载来拍摄自己的脚.就像指针一样,人们会犯愚蠢的错误,因此决定将剪刀拿走.

至少我认为这就是原因.无论如何我都在你身边.:)



9> Volksman..:

有人说Java中的运算符重载会导致混淆。那些人是否曾经停下来看一些Java代码做一些基本的数学运算,例如使用BigDecimal来增加财务价值?....这种做法的冗长性成为其自身对混淆的证明。具有讽刺意味的是,将运算符重载添加到Java中将使我们能够创建自己的Currency类,这将使此类数学代码既优雅又简单(减少混淆)。

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有