昨日調試一個小程式,發現java.lang.Object的克隆操作在多維數組的識別上並非智能,需要謹慎使用.
先寫個父類A如下:
public class A {
int[][] data;
public A(int[][] a){
data = a;
}
}
子類B繼承它:
public class B extends A {
int[][] data2;
public B(int[][] b) {
super(generateAData(b));
this.data2 = b;
}
public static int[][] generateAData(final int[][] b_init){
if(b_init==null)return new int[LENGTH][LENGTH];
else{
int[][] toInitA = b_init.clone();
setUnit(toInitA);
return toInitA;
}
}
private static void setUnit(int[][] toInitA) {
for(int i=0;i<toInitA.length;++i){
for(int j=0;j<toInitA[i].length;++j){
if(i==j)toInitA[i][j]=1;
}
}
}
public static final int LENGTH = 10;
}
現在,我們初始化一個B的實例,把一個初值寫入子類成員,並且將此值做了一份clone并更改部份數據,寫入父類A的成員變量中.這樣結果就來了,打印出來發現兩個成員變量(父類的和子類的)是一樣的...
main函數測試樣例如下:
public static void main(String[] args) {
int[][] bdata = {{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}};
A a = new B(bdata);
System.out.println("A.data: ");
for(int i=0;i<a.data.length;++i){
for(int j=0;j<a.data[i].length;++j){
System.out.print(a.data[i][j] +" ");
}
System.out.println();
}
System.out.println("B.data2: ");
for(int i=0;i<((B)a).data2.length;++i){
for(int j=0;j<((B)a).data2[i].length;++j){
System.out.print(((B)a).data2[i][j] +" ");
}
System.out.println();
}
}
輸出結果為:
A.data:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
B.data2:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
看來儘管我們在設置A的成員變量的靜態函數(此函數被構造函數super()調用,此時實例還未生成,故只能用靜態方法)的入參使用了final修飾,但絲毫沒有起作用.
看起來這是迷思沒辦法破除,實際上,很好理解,因為java.lang.Object的clone()操作只是把這個二維數組對象的成員,即每個行變量複製到了新的記憶體地址,但由於是二維數組,每個行變量里存的仍然是"指針",造成了新數組的N個行變量和舊數組的N個行變量都指向了原來的舊記憶體區塊,新賦值給任何一個數組尋址(operator[])的lvalue名稱,無論新的還是舊的,改動的,實際上都是一份copy,因為只有一份真正的copy存貨.
綜上所述,在寫程式時候,都要對所用的每一個API或者賦值過程都要有清楚而準確的把握,否則這樣的問題,如果出現在一個大的程式當中,一定將是非常惱人的.
分享到:
相关推荐
本项目是使用Java开发的一个分布式海量小文件存储系统,功能包括文件上传、文件下载、文件存储等,解决了海量小文件在存储和访问过程中遇到的各种性能问题。 本项目是使用Java开发的一个分布式海量小文件存储系统,...
Java小程序,也称为Java Applet,是用Java语言编写的轻量级应用程序,可以在Web浏览器中运行,为用户提供互动体验。这些小程序可以是各种类型的游戏,例如坦克大战、吃蘑菇游戏、乒乓球游戏和打字游戏,以及一些实用...
在Java编程语言中,开发一个小程序是一个非常常见的学习和实践任务。这个“java写的一个小程序”显然是一款基于Java实现的抽奖程序,对于初学者来说,它提供了了解和掌握Java编程基础,以及学习如何构建实际应用的...
综上所述,“Java小工具”集合可能包括用于查看源码的JD-GUI,用于搜索jar包类的JarClassSearch,以及一个清理Subversion设置的注册表脚本。这些工具在Java开发环境中扮演着不可或缺的角色,提高了开发者的生产力和...
《一个小的JAVA计算器》 在IT领域,编程是解决问题的核心工具,而JAVA作为一种广泛应用的编程语言,被广泛用于开发各种应用程序。本项目“一个小的JAVA计算器”是一个简单的JAVA程序,旨在帮助初学者理解和掌握JAVA...
学习和开发Java小游戏是一个很好的实践编程技巧的方式,尤其是对于初学者来说。它不仅可以加深对Java语言的理解,还可以提升问题解决能力和逻辑思维能力。随着技能的提高,你可以尝试开发更复杂的游戏,比如角色扮演...
【文件名称列表】:由于提供的信息只有一个总文件名“java贪吃蛇小游戏代码java小游戏源码”,我们可以假设压缩包内包含了多个相关的Java类文件,如Game.java(主程序类)、Snake.java(蛇的类)、Food.java(食物类...
本合集包含的15个Java小游戏源码提供了丰富的学习资源,适合初学者理解游戏编程的基本原理,同时也可作为进阶开发者研究和优化代码的参考。下面将详细探讨这些游戏的编程知识点。 1. **Java打猎射击游戏**: - ...
Java小游戏开发是一个很好的实践项目,尤其适合初学者熟悉编程语言特性和面向对象设计。这个压缩包包含了一个基于Java实现的小游戏源代码,可以为初学者提供一个实际操作的平台,帮助他们更好地理解和应用Java编程...
以上是对“第一个Java程序”的详细解析,包括基础知识、编译执行流程、常见问题解决办法、语法要点以及一个简单的实践任务。通过这些内容的学习,初学者能够更好地理解Java程序的基本概念和开发流程。
Java小游戏源码集合是一个丰富的资源库,包含了八款经典的Java编程实现的小游戏,这些游戏能够帮助初学者理解和学习Java编程语言以及游戏开发的基本原理。以下是这些游戏的详细讲解: 1. **五子棋**:五子棋是一款...
标题 "一个JAVA做的小游戏" 暗示了我们讨论的主题是一款使用Java编程语言开发的娱乐应用程序,这可能是基于PC或移动设备的小型互动游戏。Java是一种广泛应用的面向对象的编程语言,以其“一次编写,到处运行”的特性...
以下是对给定的四个Java小程序的详细解释: 1. **判断闰年程序**: 这个程序的任务是根据给定的年份来判断是否是闰年。在Java中,我们使用`Scanner`类获取用户输入的年份,然后通过条件语句进行判断。闰年的规则...
《JAVA经典100个小案例》是一份专为初学者设计的Java编程资源,它包含了100个精心挑选的实例,旨在帮助新手快速掌握Java编程的...对于初入Java世界的人来说,这是一个极好的起点,能够让你在实践中学习,在学习中进步。
标题中的“java 自己写的小球在一个矩形框内反弹程序”揭示了这是一个基于Java编程语言的项目,目的是实现一个动态的小游戏。在这个游戏中,一个小球会在一个矩形区域内运动,并且当它碰撞到边界时,会按照物理定律...
本文介绍了如何编写一个简单的Java小程序来统计字符串中的字母数量。通过分析代码逻辑、关键API以及可能的改进方向,我们可以更好地理解和应用这些技术。这个小程序不仅适用于初学者学习基本的Java编程概念,而且还...
在这个项目中,我们看到一个由Java实现的聊天程序,它提供了一个基础的交互平台,供用户进行实时交流。下面,我们将深入探讨Java在创建聊天应用程序时涉及的关键知识点。 首先,Java的核心特性使其适合构建这样的...
如何以最低的经济代价建设这个通信网,是一个网的最小生成树问题。(1)利用克鲁斯卡尔算法求网的最小生成树。 (2)实现教科书中定义的抽象数据类型MFSet。以此表示构造生成树过程中的连通分量。 (3)以文本形式输出...
Java编程语言是软件开发领域广泛使用的工具,尤其对于初学者来说,它提供了丰富的...建议按照顺序逐步学习,每完成一个小程序都要自己动手尝试,遇到问题时查阅文档或在线求助,这样可以巩固知识,提高解决问题的能力。