资讯专栏INFORMATION COLUMN

JAVA语法糖“+”运算符

Meils / 2743人阅读

摘要:提供的运算符,如,从的角度来看总是想找到是怎么重载这个运算符,于是进去这个类中看,然而并没有什么卵发现,于是乎想着是怎么做到的下面来为你逐步分析下是怎么实现操作符重载的。

JAVA提供的“+”运算符,如Iteger+String,从C++的角度来看总是想找到JAVA是怎么重载这个“+”运算符,于是进去String这个类中看,然而并没有什么卵发现,于是乎想着JAVA是怎么做到的?下面来为你逐步分析下JAVA是怎么实现“+操作符重载的”。

示例
public class Example {

    public static void main(String[] args) {
        Integer a = null;
        String b = a + "456";
        System.out.println(b);
    }
}

这个程序很简单就是一个Integer和String的“+”运算表达式。运行结果:
null456

反编译示例程序

命令:javap -c Example

反编译后的结果如下:

Compiled from "Example.java"
public class com.boyu.budmw.test.Example extends java.lang.Object{
public com.boyu.budmw.test.Example();
  Code:
   0:    aload_0
   1:    invokespecial    #1; //Method java/lang/Object."":()V
   4:    return

public static void main(java.lang.String[]);
  Code:
   0:    aconst_null
   1:    astore_1
   2:    new    #2; //class java/lang/StringBuilder
   5:    dup
   6:    invokespecial    #3; //Method java/lang/StringBuilder."":()V
   9:    aload_1
   10:    invokevirtual    #4; //Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
   13:    ldc    #5; //String 456
   15:    invokevirtual    #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   18:    invokevirtual    #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   21:    astore_2
   22:    getstatic    #8; //Field java/lang/System.out:Ljava/io/PrintStream;
   25:    aload_2
   26:    invokevirtual    #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   29:    return

}

我们来分析下main函数部分:
0:将常量null压入操作数栈
1:从操作数栈中将null弹出保存到索引为1的局部变量a中
2:new一个StringBuilder
5:复制之前new出来的空间并将其压入操作数栈
6:调用进行初始化
9:将结果保存到操作数栈
10:调用StringBuilder.append(java/lang/Object)
13:将“456”压入栈顶
15:StringBuilder.append(java/lang/String)
18:执行toString函数

从上面的分析我们可以看到其最终是先生成了一个StringBuilder对象,之后的“+”操作符都是调用了StringBuilder.append()进行“+”的。这就可以解释上面示例程序运行后为什么是null456了,append object的时候调用了

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

将object转化为String了。

示例2
private static void pS(String... strings) {
    for (String s : strings) {
        doSomething();
    }
}

pS("123", "456");

上面的代码反编译后可以看到其实最终是将pS中的多个字符串作为一个数组传给了strings,然后遍历strings这个数据进行操作。

为什么JAVA不支持操作符重载

像C++中类对操作符进行了重载,个人觉得会操作维护难得问题,因为操作符重载没有一个标准来约束大家都可以想当然的进行重载会造成语义相差大,可读性严重降低,所以java中去掉操作符重载这个特性和他的高级面向对象很相符。so,不纠结这个问题。

后记

这都是在开发过程中会经常使用的一些东西但是可能在平时开发过程中没有挖的这么深入,都想当然了,后面可以尝试不断挖掘这些不被发现的小case。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66120.html

相关文章

  • 为什么不建议在for循环中使用"+"进行字符串拼接

    摘要:使用可以方便的对字符串进行拼接。该方法使用进行声明,说明是一个线程安全的方法。所以,阿里巴巴开发手册建议循环体内,字符串的连接方式,使用的方法进行扩展。但是,还要强调的是如果不是在循环体中进行字符串拼接的话,直接使用就好了。 摘要: 学习阿里巴巴Java开发手册。 原文:为什么阿里巴巴不建议在for循环中使用+进行字符串拼接 微信公众号:Hollis Fundebug经授权转载,...

    caoym 评论0 收藏0
  • Java语法的编译结果分析(一)

    摘要:操作对应字节码中的个字节我们可以看到最关键的操作其实就是调用的其实是类的方法,此方法的入参类型是,返回值类型是,翻译过来就是类的方法,执行完后将获得的结果做了,检查返回的对象类型是否是。 语法糖(Syntactic Sugar)的出现是为了降低我们编写某些代码时陷入的重复或繁琐,这使得我们使用语法糖后可以写出简明而优雅的代码。在Java中不加工的语法糖代码运行时可不会被虚拟机接受,因此...

    zhangxiangliang 评论0 收藏0
  • JAVA语法语法编译

    摘要:提供给了用户大量的语法糖,比如泛型自动装箱拆箱循环变长参数内部类枚举类断言新特性方法引用等解语法糖语法糖的存在主要是方便开发人员使用。 首先,部分总结文字引用 简书作者:Eric新之助 。链接:https://www.jianshu.com/p/4de08deb6ba4 已获得授权 showImg(https://segmentfault.com/img/bVbfuX9?w=646&...

    weakish 评论0 收藏0
  • 【算法日积月累】1-选择排序

    摘要:选择排序算法实现实现选择排序,记录最小元素的索引,最后才交换位置说明交换两个数组中的元素,在中有更简单的写法,这是的语法糖,其它语言中是没有的。和语言中比较器的实现前面我们说到了,我们为了突出排序算法的思想,将所有的例子仅限在数组排序中。 showImg(https://segmentfault.com/img/remote/1460000017909538?w=1949&h=1080...

    neuSnail 评论0 收藏0
  • Hollis原创|不了解这12个语法,别说你会Java

    摘要:但其实,虚拟机并不支持这些语法糖。方式为每个泛型类型创建唯一的字节码表示,并且将该泛型类型的实例都映射到这个唯一的字节码表示上。GitHub 2.5k Star 的Java工程师成神之路 ,不来了解一下吗); GitHub 2.5k Star 的Java工程师成神之路 ,真的不来了解一下吗); GitHub 2.5k Star 的Java工程师成神之路 ,真的确定不来了解一下吗); 本文从 ...

    番茄西红柿 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<