今天被Java引用与内存的关系坑了两把。
第一把:
1 public class VipOperat { 2 3 VipServicer[] vips = new VipServicer[1024]; 4 int peopleOfCount = 0; 5 6 public void add(VipServicer vip) { 7 vips[peopleOfCount] = vip; 8 peopleOfCount++; 9 } 10 11 public void showVips() { 12 System.out.println("***会员列表***"); 13 System.out.println("编号\t积分"); 14 for (int i = 0; i < peopleOfCount; ++i) { 15 System.out.println(vips[i].num + "\t" + vips[i].rating); 16 } 17 } 18 19 }
package edu.yh.java1701.linfm.javalogic.ch10.prc02; import java.util.Scanner; public class VipOperatTest { public static void main(String[] args) { VipOperat vipOperat = new VipOperat(); VipServicer vipServicer = new VipServicer(); Scanner input = new Scanner(System.in); for (int i = 0; i < 5; ++i) { System.out.print("请输入会员编号:"); String num = input.next(); vipServicer.num = num; System.out.print("请输入会员积分:"); int rating = input.nextInt(); vipServicer.rating = rating; vipOperat.add(vipServicer); } System.out.println(); vipOperat.showVips(); input.close(); } }
运行后,发现数组里面的内容是一样的,233...
原因在于,vipServicer分配了一次内存,而将其内存地址,传进数组五次,最后一次进行修改后,数组里面的五个元素(其实只有一个),就都是vipServicer最后的状态了
解决办法有二:
1.在测试类中,每次添加客户信息时,都为vipServicer分配一次内存,这样就保证内存不冲突
2.在vipServicerOperat类中,add(VipServicer vip)进行保存信息时,不赋值vip引用,而是分配内存,复制其内容(推荐,优点很明显,把这种危险,解决在设计中,而非在客户端时候时,进行使用上的限制)
第二把:
来自别人的提问, 问题是,程序在运行至16行:member[i].num = input.nextInt();时出现空指针异常.
我先简要看了下,咦,member分配了啊, input也分配了啊,怎么会这样.看了会找不出问题,我直接向她要了全部代码.
运行-果然空指针,看整体代码,没问题, debug跳转了好久也没看出问题...233
百思不得其解,然后就...豁然顿悟,虽然分配了数组空间,但这不是只分配了数组中引用的空间吗?根本没有给引用分配内存,当然空指针异常...233
总结:
虽然Java没有指针了,其实对内存管理的安全仍然存在,而且由于对Java内存管理的信任,往往导致内存问题更加隐蔽。(好像让我栽跟头的只是基础知识而已,233,但是不管怎样,这逼格还得装得高大上点)