java 赋值运算符 重载_为什么Java不提供操作符重载?

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

我觉得我必须澄清“操作符超载”的概念,为这个概念提供另一种观点。

代码混淆?

这个论点是谬论。

混淆在所有语言中都是可能的.。

通过函数/方法混淆C或Java中的代码就像在C+中通过操作符重载一样容易:// C++T operator + (const T & a, const T & b) // add ?{

T c ;

c.value = a.value - b.value ; // subtract !!!

return c ;}// Javastatic 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的标准接口中

另一个例子,让我们看看Cloneable界面在Java中:

您应该克隆实现此接口的对象。但你可以撒谎。创建一个不同的对象。实际上,这个接口太弱了,您可以完全返回另一种类型的对象,只是为了好玩:class MySincereHandShake implements Cloneable{

public Object clone()

{

return new MyVengefulKickInYourHead() ;

}}

就像Cloneable接口可能被滥用/混淆,是否应该基于C+操作符过载应该被禁止?

我们可以超载toString()a的方法MyComplexNumber类返回一天中的紧张时间。如果toString()也禁止超载?我们可以破坏MyComplexNumber.equals要让它返回一个随机值,修改操作数.。等等。

在Java中,就像在C+或其他语言中一样,程序员在编写代码时必须遵守最低限度的语义。这意味着实现add函数添加,以及Cloneable实现方法的克隆,以及++运算符而不是增量。

到底是什么弄糊涂了?

既然我们知道即使通过原始的Java方法也可以破坏代码,那么我们可以问问自己C+中操作符重载的实际使用情况吗?

清晰和自然的表示法:方法还是操作符重载?

下面我们将对Java和C+中的“相同”代码进行比较,以便更清楚地了解哪种编码风格。

自然比较:// C++ comparison for built-ins and user-defined typesbool    isEqual          = A == B ;bool    isNotEqual       = A != B ;boo

l    isLesser         = A 

= A.equals(B) ;boolean isNotEqual       = ! A.equals(B) ;boolean isLesser         = A.comparesTo(B) 

OrEqual  = A.comparesTo(B) <= 0 ;

请注意,只要提供操作符重载,A和B可以是C+中的任何类型。在Java中,当A和B不是原语时,代码会变得非常混乱,甚至对于类似于原语的对象(BigInteger等等).

自然数组/容器访问器和订阅:// C++ container accessors, more naturalvalue        = myArray[25] ;         // subscript operatorvalue        = myVector[25] ;

// subscript operatorvalue        = myString[25] ;        // subscript operatorvalue        = myMap["25"] ;

// subscript operatormyArray[25]  = value ;               // subscript operatormyVector[25] = value ;

// subscript operatormyString[25] = value ;               // subscript operatormyMap["25"]  = value ;

// subscript operator// Java container accessors, each one has its special notationvalue

= myArray[25] ;         // subscript operatorvalue        = myVector.get(25) ;

// method getvalue        = myString.charAt(25) ; // method charAtvalue

= myMap.get("25") ;     // method getmyArray[25]  = value ;

// subscript operatormyVector.set(25, value) ;

// method setmyMap.put("25", value) ;             // method put

在Java中,我们看到每个容器都要做相同的事情(通过索引或标识符访问其内容),我们有一种不同的方法来完成它,这是令人困惑的。

在C+中,由于运算符重载,每个容器使用相同的方式访问其内容。

自然高级类型操作

下面的示例使用Matrix对象,使用在google上找到的第一个链接查找Java矩阵对象“和”C+矩阵对象":// C++ YMatrix matrix implementation on CodeProject//

// 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

这并不局限于矩阵。这个BigInteger和BigDecimalJava类也有着同样令人困惑的冗长,而它们在C+中的等价物与内置类型一样清晰。

自然迭代器:// C++ Random Access iterators++it ;                  // move to the next item--it ;

// move to the previous itemit += 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" iteratorsvalue = it.next() ;

// move to the next item & return the valuevalue = it.previous() ; // move to the previous item & return the valueit.set(3.1415) ;

// sets the value 3.1415 to the current item

自然函子:// C++ FunctorsmyFunctorObject("Hello World", 42) ;// Java Functors ???myFunctorObject.execute("Hello World", 42) ;

文本连接:// C++ stream handling (with the <

stringStream   <

fileStream     <

outputStream   <

networkStream  <

" World" ;// Java concatenationmyStringBuffer.append("Hello ").append(25).append(" World") ;

好的,在Java中您可以使用MyString = "Hello " + 25 + " World" ;太.。但是,等等,这是操作符超载,不是吗?这不是作弊吗?

-D

通用代码?

相同的通用代码修改操作数应该可以用于内置/原语(在Java中没有接口)、标准对象(不能拥有正确的接口)和用户定义的对象。

例如,计算任意类型的两个值的平均值:// C++ primitive/advanced typestemplateT 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 complexMatrix  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+中见过太多人滥用它。

请将高斯林的课文与Stroustrup的文字作一比较:许多C+设计决策的根源在于我不喜欢强迫人们以某种特定的方式做事[.]很多时候,我想要取缔我个人不喜欢的一个功能,我不这么做是因为我认为我没有权利把我的观点强加于人。.

比昂·斯特鲁普。资料来源:C+的设计和演变(1.3一般背景)。

操作符重载对Java有好处吗?

有些对象将大大受益于操作符重载(具体或数字类型,如BigDecimal、复数、矩阵、容器、迭代器、比较器、解析器等)。

在C+中,您可以受益于Stroustrup的谦逊。在Java中,你只是因为高斯林的个人选择.

它能添加到Java中吗?

现在Java中不添加操作符重载的原因可能是内部策略、对特性的过敏、对开发人员的不信任(您知道,那些似乎困扰Java团队的破坏者)、与以前JVM的兼容性、编写正确规范的时间等等。

所以不要屏住呼吸等待这个特征.。

但他们是在C#!

是啊.。

虽然这并不是这两种语言之间唯一的区别,但这一种语言总是让我感到好笑。

很明显,C#的人“每一个原语都是struct,以及struct派生自对象“一开始就知道了。

他们在其他语文!!!

那么多的语言,有那么多不同的(有时甚至是相反的)哲学,但他们在这一点上都是一致的。

思想的食粮.。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值