五、String在Java中是传“引用”
这个是Java的经典问题。许多类似的问题在stackoverflow被提问,有很多不正确或不完备的答案。如果不想太多你会认为这个问题比较简单。( The question is simple if you don't think too much.)如果你想的多的话,它会非常让你困扰。
1、 下面的代码片段是有有趣和让人困惑的
public static void main(String[] args) {
String x = new String("ab");
change(x);
System.out.println(x);
}
public static void change(String x) {
x = "cd";
}
将会打印“ab”。
在C++里面,代码如下:
void change(string &x) {
x = "cd";
}
int main(){
string x = "ab";
change(x);
cout << x << endl;
}
它会打印“cd”。
2、 共同困惑问题
X存储指向堆中字符串“ab”的引用。当x作为change()方法参数时候,它仍然指向堆中的“ab”如下图:
因为Jva是传值的,x的是“ab”的引用。当方法change()被调用时,
它创建个新的“cd”对象,x现在指向“cd”如下:
这看起来像是非常很里的解释,它们清晰的描述了Java中按值传递。
但是这里有什么错吗?
3、 代码实际上怎么做的?
上面解释有几个错误。为了方便理解,简单跟踪整个过程是个好主意。
当字符串“ab“被创建时,Java分配了大量的内存去存在这个字符串对象。因此,这个对象被赋值给变量x,这个变量实际被赋值给这个对象的引用。引用是一个存在这个对象的内存地址。
变量x存储一个字符串对象的引用。但是x不是自己不是引用。它是一个存储引用的变量(内存地址)。
Java只有传值。当x被传递给change()方法时,一份x值(一个引用)的拷贝被传递。当change()方法创建另外一个“cd“对象时候,它有个不同的引用。变量x改变了它的引用(指向”cd“),而不是引用自己。
下图显示了实际发生的。
4、 错误的解释
第一个代码片段的问题与字符串的不可变性无关。即使用StringBuilder替代String,结果仍然相同。关键是变量存储了引用,但是不是引用本身。
5、 这个问题的解决
如果我们真的需要改变对象的值。首先对象必须是可以改变的,比如StringBuilder。其次,我们需要确定没有新的对象被创建和备复制给参数变量,因为java是只能值传递的。
public static void main(String[] args) {
StringBuilder x = new StringBuilder("ab");
change(x);
System.out.println(x);
}
public static void change(StringBuilder x) {
x.delete(0, 2).append("cd");
}
五、String在Java中是传“引用”的更多相关文章
- Java中对象和引用的理解
偶然想起Java中对象和引用的基本概念,为了加深下对此的理解和认识,特地整理一下相关的知识点,通过具体实例从两者的概念和区别两方面去更形象的认识理解,再去记忆. 一.对象和引用的概念: 在Java中万 ...
- Java中四种引用:强、软、弱、虚引用
这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...
- Java中构造函数传参数在基本数据类型和引用类型之间的区别
Java中构造函数传参数在基本数据类型和引用类型的区别 如果构造函数中穿的参数为基本数据类型,如果在函数中没有返回值,在调用的时候不会发生改变:而如果是引用类型,改变的是存储的位置,所有不管有没有返回 ...
- 三、为什么String在Java中是不可更改的
String在Java中是个不可更改的类.一个不可更改的类简单来说就是这个类的所有实例是不可以更改的.所有的实例信息在创建的时候被初始化而且信息是不可以更改的.不可更改的类有很多好处.这篇文章总结了为 ...
- 为什么 String 在 Java 中是不可变的?
我最喜欢的 Java 面试问题,很棘手,但同时也非常有用.一些面试者也常问这个问题,为什么 String 在 Java 中是 final 的.字符串在 Java 中是不可变的,因为 String 对象 ...
- 理解Java中的弱引用(Weak Reference)
本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...
- 为什么 String 在 Java 中是不可变的(终极答案)
为什么 String 在 Java 中是不可变的(终极答案) 我们可以从2个角度去看待这个问题: 1.为什么要设计成不可变2.如何保证不可变? 1.为什么设计不可变? 1.String对象缓存在Str ...
- java传值和传引用区别
1. 在java中所有的参数都是传值的,引用符号&的传递是C++中才有的:2. 在java传参中,基本类型(byte--short--int--long--float--double--boo ...
- 在Java中动态传参调用Python脚本
最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写java接口和复用已有的python脚本的两条路中选择了后者,但是其实后者并没有好很多,因为我是一个对python的认识仅限于其名称 ...
随机推荐
- webpack 编译ES6插件babel-loader
1.安装babel-loader 参考:http://babeljs.io/docs/setup/#installation 进入项目目录执行安装命名: npm install --save-dev ...
- Java 基础【13】 I/O流概念分析整理
转载地址:http://blog.csdn.net/yuebinghaoyuan/article/details/7388059 java.io 中的流,可以从不同的角度进行分类. 按照数据流的方向不 ...
- 解决Cydia出现红字提示“Sub-process/usr/bin/dpkg returned an error code(2)
进入此路径/var/lib/dpkg/,修改红框中的文件名,依次修改为:"available" 重新命名为 "available-bak":"stat ...
- [Python]网络爬虫(九):百度贴吧的网络爬虫(v0.4)源码及解析
转自:http://blog.csdn.net/pleasecallmewhy/article/details/8934726 百度贴吧的爬虫制作和糗百的爬虫制作原理基本相同,都是通过查看源码扣出关键 ...
- Android Listview 隐藏滚动条
在<ListView>标签中设置属性. android:fastScrollEnabled="false" 以下属性scrollbars可以设置为none也可以不设置为 ...
- JavaScript中的数组与伪数组的区别
在JavaScript中,除了5种原始数据类型之外,其他所有的都是对象,包括函数(Function). 基本数据类型:String,boolean,Number,Undefined, Null 引用数 ...
- 【LeetCode】64. Minimum Path Sum
Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to b ...
- Android学习系列(18)--App工程结构搭建
本文算是一篇漫谈,谈一谈关于Android开发中工程初始化的时候如何在初期我们就能搭建一个好的架构. 关于android架构,因为手机的限制,目前我觉得也确实没什么大谈特谈的,但是从开发的 ...
- Jersey框架
我从别人博客那儿搬点东西过来,原博请看最下面~看的顺序反了..应该先看JAX-RS整体的东西再看具体实现的Jersey例子的= =无数次改这个日记了不能忍...所以决定把JAX-RS系列的文章搬过来. ...
- iOS开发 - 用AFNetworking实现https单向验证,双向验证
https相关 自苹果宣布2017年1月1日开始强制使用https以来,htpps慢慢成为大家讨论的对象之一,不是说此前https没有出现,只是这一决策让得开发者始料未及,博主在15年的时候就做过ht ...