在实际生产项目中遇到这样的问题,如,传数据给一个方法进行处理,返回处理后的数据,处理的过程中可能出现不是异常的 但是影响结果的情况,需要拿到数据的同时判断是否发生了意外。我能想到的解决方法是 1,在数据的数据结构中标记异常
2,传递一个其他对象进去记录异常 那么关于方法2,我搜了一篇文章来更好的理解.
---------------------------------------------------------------------------------
经典的问题,但却不容易弄懂,尤其对有c基础的java程序员来说,更容易引起混乱,这里我试图简单点描述。
“java函数是传值的,java函数传递的参数是对象的引用”
这两句话好像初听上去有些矛盾,但却是事实,因而引起很多初学者的混乱。在这里我试图据个简单的例子来说明java的这个特性,可能不全面,希望大家来补全。
public class TestRef {
public static void main(String[] args)
{
ValueObject vo1 = new ValueObject("A", 1);
System.out.println("after vo1: " + vo1.getName()); //=A
changeValue1(vo1);
System.out.println("after changeValue1: " + vo1.getName());
//=A1, changed
changeValue2(vo1);
System.out.println("after changeValue2: " + vo1.getName());
//=A1, changeValue2内部的赋值不会影响这里。
}
/**
* 使用vo1自身的函数对其内部数据进行改变是有效的,函数外可反映出来
* 这种object称为可变的(mutable)
* @param vo1
*/
private static void changeValue1(ValueObject vo1) {
vo1.setName("A1");
}
/**
* 在函数内给vo1重新赋值不会改变函数外的原始值
* @param vo1
*/
private static void changeValue2(ValueObject vo1) {
vo1 = new ValueObject("B", 2);
System.out.println("inside changeValue2: "+ vo1.getName());
//=B,赋值操作引起的结果变化仅在changeValue2内部有效
}
}
class ValueObject {
public ValueObject() {}
public ValueObject(String name, int id)
{
this.name = name;
this.id = id;
}
private String name;
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
解释,vo1作为一个object,当它被用作函数参数的时候传递给函数的是一个
引用值,这个名称有点怪,又有引用又有值,到底是引用还是值呢,就看你怎么理解了。如果你是去考试,官方的答案是值。可是看起来又象引用啊,希望从这个例子,你能理解java参数传递和和C/C++程序中的引用传递的不同的地方。另外,这也是java作为OO语言的特性之一:封装的体现。
先讲一下对象赋值的关系,举例来说,下列代码:
ValueObject v2, v3;
v2 =
new ValueObject("C", 3); 粗体的部分创建了一个数据结构,假设存放在内存地址A000,赋值给句柄 v2
v3 =
new ValueObject("D", 4); 粗体的部分创建了一个数据结构,假设存放在内存地址B000,赋值给句柄 v3
v2 = v3; 这句话的作用是把操作B000的地址的句柄的值付给了v2的句柄,使得v2和v3一样操作B000的地址,这意味着:
1.原来v2指向的地址A000变成无主的内存地址,将自动被jvm回收。
2.既然v2和v3指向同一片地址,对v3的修改v2也能得到,反之亦然。
整理得下列代码,请感兴趣的朋友运行验证
ValueObject v2 = new ValueObject("C", 3);
ValueObject v3 = new ValueObject("D", 4);
v2 = v3;
System.out.println("after v2=v3");
System.out.println("v2= "+ v2.getName());//=D
System.out.println("v3= "+ v3.getName());//=D
v3.setName("C1");
System.out.println("after v3 setnameTo C1");
System.out.println("vo2= "+ v2.getName());//=C1
System.out.println("vo3= "+ v3.getName());//=C1
因此,可以得出结论,java中对象的每个实例(instance, 比如vo1, v2, v3 都是ValueObject的实例)的内存地址是唯一的,它一旦被创建,能够对这个地址进行操作的就是每个实例自己,如果ValueObject类中没有public void setName之类的方法对这个类的实例中的数据进行修改的话,程序是没有任何别的方法可以修改ValueObject类的实例中的数据,这个就是java的封装特性。对于不提供修改内部数据的方法的类,我们称为不可变(immutable)的类。在函数中对传入的参数变量进行
赋值操作,只能在
函数范围内改变局部变量指向的引用地址,但是不会改变原始地址的内容。因此,在changeValue2(...)函数内部的vo1和函数外的vo1虽然名字相同,但是实际上是不同的实例变量,只不过指向了和函数外的vo1同样的地址,所以当我们用vo1=... 对其进行赋值的时候,只不过是把函数内的临时变量指向了新的地址,并没有改变原始vo1内存地址中的内容。这就是在运行changeValue2(...)之后,vo1的值在main范围内仍然没有被修改的原因。而changeValue1里面是调用的ValueObject本身的function来更改其内容,因此是原始内存地址中的数据被更改了,所以是全局有效的。
分享到:
相关推荐
JAVA源码Java毕业论文:搜索引擎系统附源代码提取方式是百度网盘分享地址
base zz zz zz zz zz base zz zz zz zz zz base zz zz zz zz zz base zz zz zz zz zz
复制并覆盖%JAVA_HOME%/jre/lib/security下的local_policy.jar 和 US_export_policy.jar
关于java的笔试题,大家共享。阿里巴巴java笔试,希望对大家有用。
Java FizzBuzz 该存储库包括标准“Fizz Buzz”面试测试的各种基于 Java 的实现。 每个实现实际上都是独立的,但由于所选的实现是随机选择的,因此它们被打包为一个集体。
NULL 博文链接:https://greatwqs.iteye.com/blog/2429185
该代码利用 Java 8 lambda 和流支持来解决 FizzBuzz 问题。 持续集成是通过 CloudBees-CloudFoundry服务实现的,其中 git push 到 repo。 如果构建稳定,则会在 CloudBees 上触发构建并部署到 CloudFoundry。 ...
FizzBuzz-Java-Gradle
studyjava-zz Java再回首,重新探索这个精彩的世界。 斯人已去,独探索矣。 背景 从事Android移动开发4年(Java语言),因朋友想转行(铁路),需要带他转行入门。 朋友是电脑小白,没有任何编程经验,也没有学习过...
利用Best Fit启发式算法,解决3D物体装箱问题,Java实现,用最少的箱子装规定的物体,解决物流问题
kata-java-fizzbuzz 用Java实现的 。 它是最简单的TDD katas之一,非常适合学习。 我按照实施了它,可以在看到 当然使用TDD周期:红色 ->绿色 ->重构 音乐让您进入 参考 用英语讲 博客中有大量制作TDD的高质量视频...
聊天工具的java开发 超越QQ 天翔ZZ,有两个压缩包,一个是服务器程序,另一个是客户端程序.真的不错的哦~~~
fizz_buzz_ala_99_bottles:使用FizzBuzz的Sandi Metz的《 99瓶书》
您可以通过多种方式回答这个问题,例如您可以修改原始程序,或者使用 Python/pandas,甚至(对于我们中的虐待狂,你知道你是谁)在命令中输入一行prompt(可能包括cut 、 sort和uniq )。 好吧,现在你还有一个选择...
利用First Fit启发式算法,解决3D物体装箱问题,Java实现,用最少的箱子装规定的物体,解决物流问题
留言本改自柏图留言本 BTB 1.2 管理员:zz809 密 码:zz809.com
C# form1 ,form2 互相传值,form1 textbox 值传到form2 textbox, form2 textbox 值 传给 form1 textbox
fizz-buzz-gradle-java FizzBuzz Kata 使用 Gradle、Java 和 JUnit 参数化测试。
通过 FizzBuzz TDD Kata 练习 Java
deep_learning_1 包含FizzBuzz问题的神经网络实现 运行:python3 main.py --test-data <输入文件路径>