20169205 2016-2017-2 《移动平台应用开发实践》第3周学习总结
20169205 2016-2017-2 《移动平台应用开发实践》第3周学习总结
教材学习内容总结
这四章的内容主要是对String、数组、Exception、Number等相关类的具体介绍。
以String对象为例,对于java中的String,有下面几个注意的地方:
- String类初始化后是不可变的
- 声明一个类的引用变量不是对象
- 字符串创建:new创建字符串时首先查看池中是否有相同值的字符串,如果有,则拷贝一份到堆中,然后返回堆中的地址;如果池中没有,则在堆中创建一份,然后返回堆中的地址
- 使用String不一定创建对象,使用new String,一定创建对象
- String对象的equal与:对于,如果作用于基本数据类型的变量,则直接比较其存储的"值"是否相等;如果作用于引用类型的变量(String),则比较的是所指向的对象的地址(即是否指向同一个对象)。
- String中使用 + 字符串连接符进行字符串连接时,连接操作最开始时如果都是字符串常量,编译后将尽可能多的直接将字符串常量连接起来,形成新的字符串常量参与后续连接。
- String是不可变字符串对象,StringBuilder和StringBuffer是可变字符串对象,String中的对象是不可变的,也就可以理解为常量,显然线程安全。StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,只是StringBuffer 中的方法大都采用了synchronized 关键字进行修饰,因此是线程安全的。
教材学习中的问题和解决过程
1、==和equals()有什么区别
在书中学习字符串操作时,这个问题困扰了我很久,先看一段程序:
public class Test {
public static void main(String[] args) {
String str = "123";
String str1 = "123";
String str2 = new String("123");
System.out.println(str == str1);
System.out.println(str1 == "123");
System.out.println(str2 == "123");
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
System.out.println(str1 == str2.intern());
System.out.println(str2 == str2.intern());
System.out.println(str1.hashCode() == str2.hashCode());
}
}
首先,根据计算机组成原理,一般引用保存再栈中而对象保存在堆中。equals()是Object类的方法,而String类重写了equals()方法,String的内部实现其实是改变了这些类型对象相等的原则,即判断对象是否相等依据的原则为判断二者的内容是否相等。了解以上内容后我们来说说String,String类的本质是字符数组char[],其次String类是final的,是不可被继承的,这点可能被大多数人忽略,再次String是特殊的封装类型,使用String时可以直接赋值,也可以用new来创建对象,但是这二者的实现机制是不同的。还有一个String池的概念,Java运行时维护一个String池,池中的String对象不可重复,没有创建,有则作罢。String池不属于堆和栈,而是属于常量池。
接下来解释上面程序的结果,第一句的含义是在String池中创建一个对象”123”,然后引用时str指向池中的对象”123”。第二句执行时,因为”123”已经存在于String池了,所以不再创建,则strstr1返回true就明白了。str1”123”肯定正确了,在String池中只有一个”123”,而str和str1都指向池中的”123”,就是这个道理。
然后就是str2”123”的问题了,显然不对,”123”是位于String池中的对象,而str2指向的是堆内存的String对象,判断的是地址,肯定不等了。
str1.equals(str2),这个是对的,前面说过,String类的equals重写了Object类的equals()方法,实际就是判断内容是否相同了。
下面说下intern()方法,在JavaDoc文档中,这样描述了intern()方法:返回字符串对象的规范化表示形式。怎么理解这句话?实际上过程是这样进行的:该方法现在String池中查找是否存在一个对象,存在了就返回String池中对象的引用。
本例中String池存在”123”,则调用intern()方法时返回的是池中”123”对象引用,那么和str/str1都是等同的,和str2就不同了,因为str2指向的是堆内存。
hashCode()方法是返回字符串内容的哈希码,既然内容相同,哈希码必然相同,那他们就相等了,这个容易理解。
2、匿名流操作问题
关于Java中涉及到流的操作,一定不要不要使用匿名流对象,以免出现异常,没有句柄,无法关闭
try
{
File file = new File("test.exe");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
//之后只关闭了一个流bis,匿名流new FileInputStream(file)没有关闭
........
}
解决
try
{
File file = new File("test.exe");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
//之后关闭两个流fis和bis
........
}
学习进度条
码云项目地址
学习目标
时间 | 学习时间目标 | 实际进行时间 |
---|---|---|
第一周 | 8 | 8 |
第二周 | 10 | 8.5 |
第三周 | 12 | 10.5 |
希望能够通过系统地学习,探索一些开源项目并改进功能,养成良好的开发习惯,形成一套完整的android生态知识体系,并能完全自主开发一款具有一定实用价值的app。