积极主动敲代码,使用JUnit学习Java

早起看到周筠老师在知乎的回答软件专业成绩很好但是实际能力很差怎么办?,很有感触。

从读大学算起,我敲过不下100本程序设计图书的代码,我的学习经验带来我的程序设计教学方法是:程序设计入门,最有效的方法要积极主动敲代码。这也就是为什么我要求同学们把教材上的代码动手敲一遍的原因。

引用一下徐宥的例子:

记得《The TeXbook》上有一个程序,Knuth让大家自己照着敲入计算机,然后还很幽默地说,实验证明,只有很少的人会按照他说的敲入这个程序,而这部分人,却是学TeX学得最好的人。看到这里我会心一笑,觉得自己的方法原来也不算笨。从此,一字不漏敲入一本书的程序成了我推荐别人学习语言的最好办法。

针对《Java程序设计》课程,我可以改写一下,实验证明:只有很少的同学会按照我说的敲入教材上的程序,而这部分人,却是学Java学得最好的人。我知道那些所谓“把书上代码都敲了,但还是搞不懂”的同学是怎么回事,所以我验收代码的第一个问题是“代码是自己敲的吗?”

好吧,我承认个别同学真的敲了代码还不明白怎么回事,问题出在敲代码没有积极主动上,为了让这部分同学掌握学习方法,我给出一个敲代码的例子。

下面有个StringBuffer的例子,代码如下:

1 public class StringBufferDemo{
2 public static void main(String [] args){
3 StringBuffer buffer = new StringBuffer();
4 buffer.append('S');
5 buffer.append("tringBuffer");
6 System.out.println(buffer.charAt(1));
7 System.out.println(buffer.capacity();
8 System.out.println(buffer.indexOf("tring"));
9 System.out.println("buffer = " + buffer.toString());
10 }
11}

作为初学者的你们,在敲代码的时候肯定会遇到很多问题:大小写,丢字母,中英文字符,文件命名等,能让这个程序顺利编译就能学到不少知识。顺便说一下,上面的代码直接拷贝是不能够用javac StringBufferDemo.java直接编译成功的,你可以试一下。

程序编译通过后,如果直接用java StringBufferDemo运行一下程序,看一下运行结果,这样学不到太多。一种较好的做法是自己先理解代码,推导一下可能的结果,如果运行结果和自己想象的一样,基本就理解了代码,否则就有知识盲点,要深入学习了。

上面的代码,第3行构建了一个空StringBuffer的对象buffer,第4、5行调用两次append后,buffer的内容应该是“StringBuffer”, Java中的函数看一下名字就差不多猜出来它的功能了,我们猜一下后面的代码的结果:

第6行:charAt(1)应该是返回字符串中的第1个字符,很可能是‘S’或‘t’,考虑到程序设计中数组等编号都是从0开始,最有可能是‘t’
第7行:capacity大概是返回字符串的容量,字符串“StringBuffer”的长度是12,猜一下,12?
第8行:indexOf是子串匹配,与第6行问题差不多,可能是1,2,最可能是1

代码编译、运行的结果是:

t
16
1
buffer = StringBuffer

看来除了第7行,其他都猜对了。这时候是该看看StringBuffer的帮助文档了。Java8 API官方文档不大好用,在Windows下的话,推荐大家下载CHM格式的Java API,这个版本的API具个检索功能,用好了,很快可以掌握举一反三的自学能力,当然要有一点点的英语基础了。补全见下图:

比如我们想对几个数进行排序,你如果知道「排序」的英文单词是「sort」,那么你可以找到一堆可以解决你问题的方法来,是不是有了在搜索引擎中使用关键词进行搜索的感觉?如下图。

我们看看StringBuffercapacity的帮助文档:

看不懂?去扇贝背单词查一下不认识的单词的意思吧,然后把单词加入自己的记忆列表吧。计算机的英语都比较简单,英语不懂,翻译成汉语也还是不懂,因为缺少的是专业知识,而不仅仅是语言。老版本的Java API有汉化版的,下面的能看懂吗?

好象没有什么帮助。我们需要通过修改代码来理解这个方法了。把上面代码中的第4、5、6、8行屏蔽掉,让buffer是个空串看看是什么结果,结果如下:

16
buffer=

哦,明白了,capacity返回的不是字符串的长度,而是目前的最大容量。那要获得字符串的长度用哪个方法?查找一下StringBuffer的Method Summary,好象应该是length(),如下图:

我们增加一行代码调用一下length():

1 public class StringBufferDemo{
2 public static void main(String [] args){
3 StringBuffer buffer = new StringBuffer();
4 buffer.append('S');
5 buffer.append("tringBuffer");
6// System.out.println(buffer.charAt(1));
7 System.out.println(buffer.capacity();
8// System.out.println(buffer.indexOf("tring"));
9 System.out.println("buffer = " + buffer.toString());
10 System.out.println(buffer.length());
11 }
12}

程序运行结果如下:

16
buffer = StringBuffer
12

这下明白了capacity()和length()的关系,前者是最大容量,默认是16,length返回当前长度。如果学过《数据结构》相关的课程并用到过extern void *realloc(void *mem_address, unsigned int newsize); 就更容易理解了。如果字符串超过16个字符呢?我们修改代码如下:

1 public class StringBufferDemo{
2 public static void main(String [] args){
3 StringBuffer buffer = new StringBuffer();
4 buffer.append('S');
5 buffer.append("tringBuffer");
6// System.out.println(buffer.charAt(1));
7 System.out.println(buffer.capacity();
8// System.out.println(buffer.indexOf("tring12345"));
9 System.out.println("buffer = " + buffer.toString());
10 System.out.println(buffer.length());
11 }
12}

程序运行结果如下:

34
buffer = StringBuffer
17

哦,超过16个字符会再分配18个字符的空间。那超过34个字符呢?你猜猜capacity()的返回值(52?54?56?还是其他值)并修改上面的代码验证一下。

其实学习Java中的任何一个新类时,首先要学习一下其构造方法,我们看一下StringBuffer的构造方法,如下图:

汉化版如下:

原来我们可以构造StringBuffer时指定其capacity的,如果不指定默认值是16,我们修改代码如下:

1 public class StringBufferDemo{
2 public static void main(String [] args){
3 StringBuffer buffer = new StringBuffer(20);
4 buffer.append('S');
5 buffer.append("tringBuffer");
6// System.out.println(buffer.charAt(1));
7 System.out.println(buffer.capacity();
8// System.out.println(buffer.indexOf("tring12345"));
9 System.out.println("buffer = " + buffer.toString());
10 System.out.println(buffer.length());
11 }
12}

程序运行结果如下:

20
buffer = StringBuffer
12

这时对capacity的理解是不是更深入了?

当然,如果能想到StringBuilderString有什么不同,到网上找一下类「《全面解释java中StringBuilder、StringBuffer、String类之间的关系》」这类的文章看看就更积极主动了。

对于Java API中的类、方法,我们学习时写个测试类很利于我们理解类和方法的功能。我们在实验二 Java面向对象程序设计中学习了单元测试和JUnit,使用JUnit改写教材上的例子是积极主动敲代码的好途径。

比如下面这个代码,equals方法的代码要好好理解。equals实现了等价关系,满足:

  • 自反性 (reflexive):对于任何一个非null的引用值x,x.equals(x)为true。
  • 对称性 (symmetric):对于任何一个非null的引用值x和y,x.equals(y)为true时y.equals(x)为true。
  • 传递性 (transitive):对于任何一个非null的引用值x、y和z,当x.equals(y)为true 且 y.equals(z)为true 则 x.equals(z)为true。
  • 一致性 (consistent):对于任何一个非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)的结果依然一致。
  • 另外还要满足:对于任何非null的引用值x,x.equals(null)必须返回false。
public class Score {

    private int No;          //学号
private int score; //成绩 public ScoreClass() { //无参数的构造方法 No = 1000;
score = 0;
} public ScoreClass(int n, int s) { //有两个参数的构造方法
No = n;
score = s;
} public void setInfo(int n, int s) { //设置成绩
No = n;
score = s;
} public int getNo() {
return No; //获取学号
} public int getScore() {
return score; //获取成绩
} @Override
public String toString() {
return No + "\t" + score;
} @Override
public boolean equals(Object obj) {
if (this == obj) { // 是否引用同一个对象
return true;
}
if (obj == null) { // 是否为空
return false;
}
if (getClass() != obj.getClass()) { // 是否属于同一个类型
return false;
}
ScoreClass other = (ScoreClass) obj;
if (other.No == No && other.score == score) {
return true;
} else {
return false;
}
}
}

参考极简单元测试示例(以除法为例),在你熟悉的Java IDE中(Intellij IDEAEclipseNetBeans)中利用JUnit写一些测试代码,要求能测到equals中的每一个return,动手试试吧!

当然,积极主动是一种学习态度,看看学姐在我另一门课如何积极主动学习的「对atime、mtime和ctime的研究」,我说多思考了吗?深度思考对一个人的成长太重要了。

进一步参考

参考资料


欢迎关注“rocedu”微信公众号(手机上长按二维码)

做中教,做中学,实践中共同进步!



积极主动敲代码,使用Junit学习Java程序设计的更多相关文章

  1. 20145314郑凯杰 《Java程序设计》第9周学习总结 积极主动敲代码

    20145314郑凯杰 <Java程序设计>第9周学习总结 教材学习内容总结 第十六章 ①JDBC(Java DataBase Connectivity) 即java数据库连接,是一种用于 ...

  2. 关于学习JAVA程序设计语言的回顾与展望

    回顾篇 时光荏苒,大学生活已然过半.看了老师分享的几篇博文,我的内心是震憾并且惭愧的.相比别人,自己做的实在是不够多,不够好.在刚刚结束的大二上半学期,我学习了JAVA初级程序设计,虽然每节课都认真听 ...

  3. 20155310 《JAVA程序设计》实验二(JAVA面向对象程序设计)实验报告

    20155310 <JAVA程序设计>实验二(JAVA面向对象程序设计)实验报告 实验内容 •初步掌握单元测试和TDD •理解并掌握面向对象三要素:封装.继承.多态 •初步掌握UML建模 ...

  4. 20155201 2016-2017-2 《Java程序设计》第二周学习总结

    20155201 2016-2017-2 <Java程序设计>第二周学习总结 教材学习内容总结 编译运行P55各种类型可储存的数值范围代码,截图: 常用格式控制符: 符号 说明 %% 表示 ...

  5. 20155202 2016-2017-2 《Java程序设计》第1周学习总结

    20155202 2016-2017-2 <Java程序设计>第1周学习总结 考核方式于成绩构成 100分构成  翻转课堂考核12次(5*12 = 60):每次考试20-30道题目,考试 ...

  6. 20155232 2016-2017-2 《Java程序设计》第1周学习总结

    20155232 2016-2017-2 <Java程序设计>第1周学习总结 认真学习考核方式,理解成绩构成 100分构成: 翻转课堂考核12次(60分) 实验5次(15分) 团队项目(2 ...

  7. 《Java程序设计》 课程教学

    <Java程序设计> 课程教学 给学生 考核方式 100分构成 翻转课堂考核12次(5*12 = 60):每次考试20-30道题目,考试成绩规格化成5分(比如总分20分就除以4) 注意:不 ...

  8. 2016-2017-2 《Java程序设计》教学进程

    2016-2017-2 <Java程序设计>教学进程 目录 考核方式 课前准备 教学进程 第00周学习任务和要求 第01周学习任务和要求 第02周学习任务和要求 第03周学习任务和要求 第 ...

  9. 2016-2017-2 《Java程序设计》预备作业2总结

    2016-2017-2 <Java程序设计>预备作业2总结 古希腊学者普罗塔戈说过:「头脑不是一个要被填满的容器,而是一束需要被点燃的火把.」 在对计算机系的学生情况的调查中,我说: 最近 ...

随机推荐

  1. JS全屏漂浮广告、移入光标停止移动

    点击这里查看效果 以下是代码: <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Ty ...

  2. 向ES6靠齐的Class.js

    写在前面 在2008年的时候,John Resig写了一 Class.js,使用的方式如下: var Person = Class.extend({ init: function(isDancing) ...

  3. Group-buy项目总结

    这是我做的第一个移动端项目,和传统PC端网站不同的是,做移动端的网站要适配各种尺寸的设备. 在默认情况下,移动设备上的viewport都是要大于浏览器可视区域的,这是因为考虑到移动设备的分辨率相对于桌 ...

  4. SharePoint 2013 工作流平台的选项不可用

    问题描述 当我想创建一个SharePoint 2013 工作流的时候,打开SharePoint 2013 Designer(一下简称SPD),发现没有SharePoint 2013 工作流的选项.原来 ...

  5. GeoEvent使用问题及解决方法整理

    假如GeoEvent的部署环境是一个典型的WebGIS架构(Portal+GIS Server),往往会遇到一些问题,例如: 问题:发布的StreamService流服务无法查看. 原因:默认发布的S ...

  6. 回收ImageView占用的图像内存

    使用方法: RecycleBitmap.recycleImageView(mSelectorView);   参数为imageview /** * 回收ImageView占用的图像内存; * 使用了本 ...

  7. PHP魔术常量

    与J2E相比PHP没有九个内置对象,但他有八个魔术变量分别是: '__LINE__' 文件中的当前行号. '__FILE__ 文件的完整路径和文件名. '__DIR__' 文件所在的目录. '__FU ...

  8. IOS开发基础知识--碎片29

    1:心跳效果,并可去除心跳 - (void)initScaleLayer { self.view.backgroundColor=[UIColor blueColor]; UIButton *myTe ...

  9. GCD

    Grand Central Dispatch(GCD)包含语言特点.运行库和系统增强功能,它提供系统的.综合的改进,进而去支持并发代码在iOS和OSX多核硬件上的执行. 子系统.CoreFoundat ...

  10. 会话技术( Cookie ,Session)

    会话技术:    会话:浏览器访问服务器端,发送多次请求,接受多次响应.直到有一方断开连接.会话结束.        解决问题:可以使用会话技术,在一次会话的多次请求之间共享数据.           ...