hello ,好久没来了。

今天我来和大家分享一下有关引用变量的注意事项,一是加深一下自己的理解,二是对这块不太理解的同学可以看看。

大神可飘过,有什么不对或不足的地方请多多指教,谢谢。

假设场景:

有一个统计游戏玩家信息调查问卷系统,玩家填写了调查问卷,会给玩家一些奖励,当然目前这不是我们关注的部分。

我们需要记录一下玩家的姓名,年龄,邮箱,以及玩家曾经玩过的游戏有哪些。

既然要记录玩家玩过的游戏,必然要有Game类:

package indi.bruce.summary;

public class Game {

    private int id;   //随便填写一个id
private String name; //总要有个游戏名字吧
private String developer; //游戏是谁开发的
private String type; //游戏总要有个类型吧 ,例如:策略,体育,动作等等 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;
}
public String getDeveloper() {
return developer;
}
public void setDeveloper(String developer) {
this.developer = developer;
} public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
} }

现在定义玩家类 Player:

package indi.bruce.summary;

import java.util.ArrayList;
import java.util.List; public class Player { private int id ; //玩家编号
private String name; //姓名
private int age; //年龄
private String email; //邮箱 private List<Game> gameList; //曾经玩过的游戏,便于分析用户行为 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;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public List<Game> getGameList() {
if(gameList == null){
return new ArrayList<Game>();
}
return gameList;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
}
}

正题开始:

假设场景1:玩家问卷数据已经存库,玩家要修改自己的信息,而系统需要记录一下到底修改了哪些地方。  

      1)从数据库读取用户的数据Player。

      2)将原来的对象player复制出来一份给temp对象,玩家修改信息在temp对象上修改(既然要记录玩家修改了什么,则需要原来的对象和现在的对象对比)。

      3)两个对象做一下对比,就可以做操作记录了。

场景1测试代码:

@Test
public void sceneOne(){
  Player player = getPlayer(1110); //从数据库获取的对象
  System.out.println("print player.getName() is:"+player.getName());   Player temp = player; //玩家修改信息全部在副本temp上操作,这样就可以对比到底玩家修改了什么信息,哈哈哈....
  temp.setName("moon"); //玩家修改了名字
  System.out.println("print temp.getName() is:" + temp.getName()); //哈哈...成功了,多简单的事情
  System.out.println("print player.getName() is:" + player.getName());   /*但是打印结果
  * print player.getName() is:sky
  * print temp.getName() is:moon
  * print player.getName() is:moon
  *
  * 疑问:为什么只是修改temp属性name的值,而player的name值也变了呢?
      */
} //假设该方法是从数据库获取该用户的数据对象,这不是我们目前关注的部分
public Player getPlayer(int id){
  Player player = new Player();
  player.setId(1110);
  player.setName("sky");
  player.setAge(20);
  player.setEmail("brucetest@indi.com");   return player; }

  

为什么会出现上面的情况呢,来分析一下引用变量的工作原理:

  1.代码中"Player player = getPlayer(1110);"做了两件事:

    1)将玩家1110数据从数据库数据库读出来(这部分假设从数据库读出来),并加载的堆内存中(player对象实际上只存在堆内存中)。

    2)新建一个引用变量player(其实就是指针)指向堆内存的player对象(也就是记录堆内存中player的内存地址)

  2.代码"Player temp = player;"做了一件事:

    新建引用变量temp,并且指向堆内存中的player对象。

  总结:所以不管是针对栈中的引用变量temp,还是栈中的引用变量player操作,实际上都是操作堆内存中的player对象。

  注意:解决场景1出现的问题,需要引入一个概念"深拷贝",概念请问度娘.

     解决方案:1)首先Player类需要实现Cloneable接口:public class Player implements Cloneable

          2)需要在Player中重写Object的clone方法

                public Object clone(){

                   Object obj = null;
                 try {
                 return super.clone();
                 } catch (CloneNotSupportedException e) {
                    e.printStackTrace();
                }
                return obj;
             }

          3)在调用的地方:Player player = getPlayer(1110); Player temp = (Player)player.clone();

java对象引用-要掌握的细节的更多相关文章

  1. java对象引用-要掌握的细节2

    目的:加深对java引用变量的理解,避免数据的处理的偏差. 问题: 1.一个集合List ,将新建Student对象stu放入List之后,再给stu的成员变量例如id,name赋值.此时List中的 ...

  2. Java编写画图板程序细节-保存已画图形

    没有Java编写画图板程序细节-保存已画图形   一.为何我们要保存画图板上已画图形呢? 有很多人会问,为什么我们一定要保存画图板上已经画好了的图形呢?原因很简单.当我们在画图板上画完自己想画的图形后 ...

  3. java对象与java对象引用的区别

    java对象与java对象引用的区别 对象与对象引用的区别 直接用例子说话吧 Person per = new Person("张三"); 这一条语句,其实包括了四个动作: 右边的 ...

  4. JAVA 对象引用,以及对象赋值

    注:引自http://zwmf.iteye.com/blog/1738574 关键字: java对象 引用 Java对象及其引用 关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里, ...

  5. Java对象引用

    1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...

  6. JAVA 对象引用,以及对象赋值(转)

    原文链接:http://zwmf.iteye.com/blog/1738574 关键字: java对象 引用 Java对象及其引用 关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里 ...

  7. Java对象引用和对象赋值

    关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里,总觉得基本概念很模糊.后来才知道,在许多Java书中,把对象和对象的引用混为一谈.可是,如果我分不清对象与对象引用,那实在没法很好 ...

  8. Java与c#的一些细节区别

    实习中用的语言是c#,第一次接触到这种语言,然后写的过程中,发觉和Java几乎一摸一样,好像根本是无缝切换,但细节仍有很大的区别,称有空总结一波里面的部分细节实现. ps. 我写c#过程中,发觉c#有 ...

  9. Java对象引用传递探索

    一直认为自己对对象传递理解的颇为深刻,没想到最近一次的编码中,就犯下了这样的错误,令自己排查了很久才找到问题的根源, 辅以小case记录以自省. 代码如下: public class ObjRefer ...

随机推荐

  1. 探讨 java中 接口和对象的关系

    接口是对象么?接口可以有对象么?这个问题要跟类比对着,或许更好理解;类是对象的模版.接口不是类,所以:接口肯定不是对象的模版.那接口跟对象有什么样的关系?还是得从类入手;因为类实现了接口,所以可以说, ...

  2. bzoj:3616: War

    Description 小x所在的世界正在经历一场在k个阵营之间的战争.每个阵营有若干个炮塔,每个炮塔由攻击系统和防御系统组成.第i个炮塔可以攻击到离它欧几里德距离小于等于ri 或者曼哈顿距离小于等于 ...

  3. Link-Cut-Trees

    填坑,填坑,填坑…… 开篇镇人品……下文的比喻仅供娱乐…… 为了迎接JSZX校内互测,我临时填坑学了LCT…… 怎么说呢……我也是懵懵懂懂地看了N篇博客,对着标程敲上一发代码,然后才慢慢理解.这里推荐 ...

  4. bzoj:3085: 反质数加强版SAPGAP

    Description 先解释一下SAPGAP=Super AntiPrime, Greatest AntiPrime(真不是网络流),于是你就应该知道本题是一个关于反质数(Antiprime)的问题 ...

  5. 2017西安网络赛 F

    f(cos(x))=cos(n∗x) holds for all xx. Given two integers nn and mm, you need to calculate the coeffic ...

  6. js取整并保留两位小数的方法

    js 四舍五入函数 toFixed(),里面的参数 就是保留小数的位数.注意 toFixed()方法只针对数字类型,如果是字符类型需要使用Number()等方法先转换数字类型再使用 document. ...

  7. Tomcat源码调试环境搭建

    我们一般都是为了解决某个问题,才去看源码的.Java体系就是这点好处,源码唾手可得.遇到问题,最后的解决方法总是可以从源码中找到. 参考了网上的文章,过程整理如下: 1. 下载和导入 官网下载编译好的 ...

  8. 【蓝桥杯单片机02】LED的基本控制

    [蓝桥杯单片机02]LED的基本控制 广东职业技术学院  欧浩源 在CT107D单片机综合训练平台实现LED的基本控制和其他单片机开发平台不一样,不单单是控制几个LED实现跑马灯这么简单.因为在这个平 ...

  9. 邓_Excal

    --------------------------------------------------------------------- 快速输入固定文字 有一些固定的词组,输入 1 个.2 个,貌 ...

  10. 数据库DBUtils基本使用

    Apache-DBUtils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,使用dbutils能极大简化jdbc编码的工作量,同 ...