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。

参考资料

原文地址:https://www.cnblogs.com/wule/p/6558743.html