`
chopsuey
  • 浏览: 4021 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

Java中的String及传参的一些浅见

    博客分类:
  • Java
阅读更多
String str = "abc";        //代码段一
String str1 = "abc";      //代码段二
str1 = "def";                //代码段三

 

        很多时候,都会有人拿类似上面的代码来问,生成了多少个对象啊?

 

        很明显,生成了两个对象,都是编译期生成的。分别是代码段一跟代码段三生成的。

 

        那代码段二呢?答案是并没有生成对象,只是把一个引用指向了”abc”对象,换言之,执行完代码段二后,str跟str1指向了同个对象。大家可以用(str == str1)来判断它们是不是指向同个对象。

 

        这样是不是说明当修改str1时,str也会跟着修改呢?答案是否定的。比如说当执行代码段三时,大家会发现,str的内容并没有变成def,还是abc。那这里面究竟发生了什么事?


        当运行代码段一时,编译器会在常量池里寻找有没有一个值为”abc”的字符串对象,哦,没有,所以它创建了一个这样的对象。当运行代码段二时,编译器在常量池里找到了一个这样的对象,所以就把str1也指向了它。当运行代码段三时,编译器又在常量池里寻找值为”def”的对象,结果发现没有,所以就再创建了一个字符串对象。因此,总结一下,上面三句代码,总共创建了两个对象。

        再看下面的代码:

String tmp = "a"+"bc";        //代码段四

        请问,这里有创建新对象吗?答案是没有的。因为括号内文本的方式都是在编译期就解决掉的。所以当运行代码段四时,编译器在常量池里寻找有没有一个值为”abc”的对象,结果是找到了,所以就把tmp指向它。由于在栈里的速度非常快,像刚刚描述的过程,事实上,只是移动一下指针,因此,效率会比用new在堆里生成对象高很多。

        强调一句,用new在堆里生成对象,不管内容是不是一样,都会生成相应的实例。比如说

String tmp = new String("chop");    //代码段五
String tmp1 = new String("chop");      //代码段六
 

        这里就铁定地生成了两个对象。虽然它们的值是一样的,但却是两个指向不同地方的引用。


关于java传值问题

        首先,在java之父所写的书里就有一句这样的话:在java里只有一种传值方式:值传递。 我们不来搞个人崇拜,权威定理。那我们就用代码来说明吧。大家猜测一下代码的输出结果是什么?

 

public class Test

{

    public void changeStr(String tmp){

        tmp = "输出修改值!";

    }

public static void main(String args[]){

Test obj = new Test();

        String str = "输出原值!";

        obj.changeStr(str);

        System.out.println(str);

    }

}
 

        很遗憾地告诉大家,结果是”输出原值!”。再联想一下值传递的想法就很清楚了。在main方法那里,生成了一个String对象,值为”输出原值”。然后有个str引用指向了它。当调用changeStr(str)方法时,就把str引用复制了一份(注意,这里是复制了一份str引用),然后再把它传递给changeStr方法。换言之,现在有两个引用指向了那个对象。在方法内部,把那个复制的引用又指向了另一个对象(其值为”输出修改值!”)。但原来那个引用所指向的对象还是没变。因此,你再打印str,自然结果还是”输出原值!”了。

 

关于String的进一步讨论

        如果大家对第一部分的讨论还有疑惑,我们可以把第二部分的代码再修改一下的,大家看一下下面的代码输出

public class Test

{

    public String changeStr(String tmp){

        tmp = "输出原值!";

        return tmp;

    }

public static void main(String args[]){

Test obj = new Test();

        String str = "输出原值!";

        String tmp = obj.changeStr(str);

         System.out.println(tmp == str);    //你觉得会输出什么呢?true或false。在java里,对于类而言,==是用来判断两个引用所指向的对象是不是同个对象的。

        System.out.println(str);

    }

}
 



        运行过代码就会发现,结果是true。也就是说,引用内文本生成的对象是放在常量池的,并且在编译期就已经解决了。

        如果我再把changeStr(String tmp)方法改一下,把tmp = “输出原值!”;改成tmp = new String(“输出原值!”);输出结果很明显就是false了。虽然它们的值是一样的,但由于是在运行时在堆里生成的对象,tmp跟str所指向的是不同对象的。

       总结一下上面所说的,大家主要是要分清楚哪些是编译期就可以确定的,哪些要运行时才能确定,哪些是在栈里的,哪些是在堆里的,这样就会很清晰了。

 

        后记:本文只是自己在编写过程中的一些想法,并不是看《深入 java 虚拟机》或是直接反汇编代码(不是不想,实在是能力还没到那个水平)来理解的,因此如果有不正确的地方,还请各位指正。

分享到:
评论

相关推荐

    83.java中String构造方法.zip

    83.java中String构造方法.zip83.java中String构造方法.zip83.java中String构造方法.zip83.java中String构造方法.zip83.java中String构造方法.zip83.java中String构造方法.zip83.java中String构造方法.zip83.java中...

    85.java中String构造方法.zip

    85.java中String构造方法.zip85.java中String构造方法.zip85.java中String构造方法.zip85.java中String构造方法.zip85.java中String构造方法.zip85.java中String构造方法.zip85.java中String构造方法.zip85.java中...

    86.java中String对象的特点.zip

    86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点....

    java基础String类选择题练习题

    根据提供的信息,我们可以总结出这份Java基础String类选择题练习题主要聚焦于String及StringBuffer类的使用。尽管具体的题目内容未给出,但从所展示的信息中可以推断出该练习题集涵盖了以下几方面的知识点: ### 一...

    Java中String类中的常用方法.TXT

    简单总结可以下Java中String类中的常用方法

    java中string和int型的相互转换.doc

    Java 中 String 和 int 类型的相互转换 Java 中 String 和 int 类型的相互转换是一个基本的数据类型转换操作。下面我们来详细介绍这两种类型的相互转换。 String 转换为 int 在 Java 中,将 String 类型转换为 ...

    小心String的陷阱——深入剖析Java中String的处理机制

    标题和描述均强调了在Java中处理`String`对象时可能遇到的陷阱,尤其是在理解和使用`String`的处理机制上。文章由天津工业大学软件工程专业的翁龙辉撰写,旨在深入剖析`String`在Java中的独特行为及其潜在的陷阱。...

    java调用shell向DataX传参,带where条件,特殊字符

    在Java程序中调用Shell命令并传入带有特殊字符的参数时,会遇到一些挑战,因为Shell和DataX对特殊字符的处理方式可能不同。 首先,让我们理解Java如何调用Shell命令。在Java中,我们可以使用Runtime或者...

    java中String_十六进制String_byte[]之间相互转换

    ### Java中String、十六进制String与byte[]之间的相互转换 在Java开发中,字符串(String)、十六进制表示的字符串以及字节数组(byte[])之间的转换是非常常见的需求,尤其是在处理网络通信、文件读写等场景下。...

    自定义注解实现伪动态传参的小demo

    在Java编程语言中,注解(Annotations)是一种元数据,用于提供有关代码的信息,这些信息可以被编译器或运行时环境使用。自定义注解是扩展Java功能的强大工具,可以用于实现各种目的,如代码生成、编译时检查、运行...

    StringUtil.java

    java编程中对字符串的各种方式的处理,包括(空字符串处理、判断是否是空字符串 null和"" 都返回 true、 把string array or list用给定的符号symbol连接成一个字符串、 判定第一个字符串是否等于的第二个字符串中的某...

    java中Blob转String

    分享在JAVA中Blob转换成String实例

    深入了解java 中的String

    深入了解Java中的String类是至关重要的,因为String在Java编程中占据着极其重要的位置。下面将对给定的信息进行深入分析: ### 1. String 类是 final 的,不可被继承 在Java中,`String` 类被声明为 `final` 类型...

    Java中颜色的String和Color对象之间的互相转换

    Java 中颜色的 String 和 Color 对象之间的互相转换 在 Java 中,颜色的表示形式有多种,包括字符串形式和 Color 对象形式。这两种形式可以互相转换,本文将介绍 Java 中颜色的 String 和 Color 对象之间的互相转换...

    java中的String类常用方法解析(一)

    在Java编程语言中,`String`类是使用最频繁的类之一,它代表不可变的字符序列。本文将深入解析`String`类的一些常用方法,帮助开发者更好地理解和使用这个核心类。 1. **构造方法** - `String()`:创建一个空字符...

    JAVA String.format方法使用介绍

    在JDK1.5中,String类增加了一个非常有用的静态函数format(String format, Objece... argues),可以将各类数据格式化为字符串并输出。其中format参数指定了输出的格式,是最复杂也是最难掌握的一点,而argues则是一...

    sprinmvc jsp与java的几种相互传参的方式

    在Spring MVC框架中,JSP(JavaServer Pages)与Java之间的数据传递是Web开发中的常见操作。本项目可能是一个Eclipse导出的Spring MVC应用,使用的`spring-webmvc-4.2.5.RELEASE`是Spring MVC的核心库,用于处理HTTP...

    java调用shell向DataX传递参数,where条件,包含特殊字符

    在Java中调用shell脚本,可以使用Runtime类或ProcessBuilder类。例如,你可以创建一个shell脚本来执行DataX的同步任务,并将where条件作为参数传递。当条件包含特殊字符(如单引号 `'`、双引号 `"`、反斜杠 `\` 或者...

Global site tag (gtag.js) - Google Analytics