Thinking in Java读书笔记(IO和并发除外)

1.1、类中所有的private方法都隐式地指定为final的,由于其他类无法取用private方法,所以也就无法覆盖它;private方法无法被重写,继承对应private的方法无效,private的属性也无法拿到,但我们通常private的属性有对应的get、set方法,通常是public的,所以子类继承后可以调用方法来取得到父类的属性。

1.2、final类禁止继承,所以final类中所有的方法都隐式地指定为final的,因此无法覆盖他们,你也可以给他们添加final关键字,但这没什么意义。

1.3、java中所有方法都是通过动态绑定来实现多态的。

1.4、如果某个方法是静态的,它的行为就不具有多态性。所以构造器不具有多态性,他们实际上是static的,只不过该static声明是隐式的。

2.1、在方法的作用域内(而不是其他类的作用域内)创建一个完整的类,这个类称为局部内部类(其实命名就和局部变量一样,在方法中的变量叫局部变量)。

3.1、Set中,HashSet拥有最快的获取元素的方式;如果存储顺序很重要,那么使用TreeSet,它按照比较结果的升序保存对象,或者使用LinkedHashSet,它按照被添加的顺序保存对象。

3.2、List中,基本的arrayList擅长随机访问元素,但是在中间插入和移除元素时会比较慢;LinkedList和arrayList相反,中间插入和删除快,随机访问慢。

3.3、ListIterator是一个更加强大的迭代器,但看名字就知道只用于List类,普通的Iterator只能向前移动,就只有hasNext(),但ListIterator可以双向移动,有hasNext()和hasPrevious()两种移动方式。

3.4、Queue是队列,典型的先进先出容器,即从一端进去,另一端出来,取出顺序和放入顺序一样。

3.5、java容器实际上就四种:Map、List、Set和Queue。下面详细地介绍一下各个容器类型的性能特点区别:

3.5.1、List:元素可以重复。

ArrayList:底层是由数组支持的;

LinkedList:是由双向链表实现的,其中的每一个对象都包含数据的同时还包含了指向链表中前一个和后一个元素的引用。

因此如果要经常在表中插入和删除元素,LinkedList比较合适。

3.5.2、Set:元素必须唯一,不允许重复,是否重复由equals()方法判定,所以加入set的元素必须定义equals()方法以确保对象的唯一性。

HashSet:为快速查找而设计的Set,其中的元素必须定义hashCode()方法,一般情况下都用他。

Treeset:保存了次序的set,底层为(平衡)树结构,使用他可以从Set中提取有序的序列,其中的元素必须实现Comparable接口(实现里面的compareTo方法)。SortedSet是TreeSet的唯一实现。

LinkedHashSet:具有HashSet的查询速度,使用链表来维护元素的顺序(这个顺序就是插入的次序),所以使用迭代器遍历他时,结果就是插入的次序,元素必须定义hashCode()方法。

3.5.3、map:保存的是键值对,key不能重复,是唯一的,可以但只能有一个为null,value可重复,可为null。

HashMap:是map基于散列表的实现(现在已经取代了HashTable)。插入和查询键值对的开销是固定的,可以通过构造器设置容量和负载因子,以调整容器的性能。通常我们都使用他。

LinkedHashMap:在HashMap的基础上保存了键值对插入的次序,访问速度比hashMap慢一点,但迭代访问时反而更快,因为内部使用链表维护内部次序。

TreeMap:基于红黑树的实现,查看键或者键值对时,他们会被排序(次序由Comparable或者Comparator决定),因此特点就是结果是排过序的,他是唯一一个具有subMap()方法的map,可以返回一个子树。SortedMap是TreeMap现阶段的唯一实现。

ConcurrentHashMap:一种线程安全的map,它不涉及同步加锁,却比HashTable或者通过加锁来实现同步的Collections.synchronizedMap(Map)得到的同步map性能更好。Collections.synchronizedMap(Map)是把一个不同步的map作为参数返回一个同步的,靠加锁来实现的。

WeakHashMap:弱键映射,允许释放映射所指向的对象,为解决特色问题而设计的。

IdentityHashMap:使用==代替equals()对“键”进行比较的散列映射,专为解决特殊问题而设计。

3.6、Object.hashCode()方法生成散列码,而它默认使用对象的地址计算散列码,除非重写他;Object.equals()默认比较对象的地址是否相同,除非你重写他。

3.7、hashmap的结构我们通常叫他散列桶,散列表中的槽位通常称为桶位,因此实际散列表的数组命名为bucket。

3.8、设计hashCode()时,最重要的因素是,无论何时,对同一个对象调用hashCode()都应该返回同样的值,当然这个对象内的属性不应该发生了变化。

3.9、java容器采用快速报错机制,他会探查容器上的任何除了你的进程所进行的操作以外的所有变化,一旦发现其他进程修改了容器,就会立刻抛出ConcurrentModificationException异常。一个简单的例子就可以看出快速报错的原理:

public static void main(String[ args){

Collection<String> c = new ArrayList<String>();

Iterator<String> it = c.iterator();

c.add("An Object");

try{

String s = it.next();

}catch(ConcurrentModificationException e){

System.out.println(e);

}

}

//输出:java.util.ConcurrentModificationException。。。

以上程序在运行时出现异常,catch后输出了异常信息,因为在容器取得迭代器后,又有东西放入到了容器中。当程序的不同部分修改了同一个容器时,就可能导致容器的状态不一致,就出现了这个异常。此例中,迭代器在获取容器后也可能会有修改容器的操作(比如iterator.remove()操作),所以在获取迭代器后,不能再调用容器的add方法改变容器,应该在获取迭代器之前就添加好元素。

3.10、在3.5中也提到了Hashtable,它和HashMap相似,甚至方法名也相似,Hashtable是同步的,但HashMap的同步问题也可通过Collections的一个静态方法得到解决: Map Collections.synchronizedMap(Map m) 这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。 所以没有理由再使用Hashtable而不用HashMap了。

4.1、Throwable对象可分为两种类型(指从Throwable继承来的类型):Error用来表示编译时和系统错误(除特殊情况外,一般不用你关心);Exception是可以抛出的基本类型。

4.2、因为finally子句一定会执行,即便在try子句中return,也会继续执行finally子句。

5.1、String对象是不可变的,String类中每一个看起来会修改String值的方法,实际上都是创建一个全新的String对象,最初的String对象则丝毫不动。

6.1、java泛型是使用擦除来实现的,这意味着当你在使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。因此List<String>和List<Integer>在运行时事实上是相同的类型,都被擦除成他们的“原生”类型--List。理解擦除以及如何处理它,是你在学习java泛型时面临的最大障碍。如下:

Class c1 = new ArrayList<String>().getClass();

Class c2 = new ArrayList<Integer>().getClass();

System.out.println(c1 == c2);//输出:true

同样的因为擦除,同一个类就不能实现同一个泛型接口的两种变体,如下:

interface A<T> {}

Class B implements A<Integer> {}

Class C extends B implements A<String> {}

类C不能编译,A<Integer>和A<String>因为擦除而简化为相同的类型A,这样C就重复实现了接口A两次了。

但是有趣的是,如果把A的泛型参数去掉,编译是可以的。如下:

interface A {}

Class B implements A {}

Class C extends B implements A {}

类C可以编译。

6.2、java泛型的限制之一:不能将基本类型用作泛型的类型参数,如ArrayList<int>之类的是不能创建的。

7.1、编译器会为你创建的enum都继承自java.lang.Enum。

7.2、枚举的values()方法返回enum实例的数组,而且该数组中的元素严格保持在enum中的声明顺序。有趣的是,你的enum中没有values()方法,你会以为是编译器会为你创建enum时继承了Enum,values方法应该在Enum这个父类里。可惜,如果你研究一下Enum类就发现也不是,Enum里也没有。答案是,values()方法是由编译器添加的static方法,是编译器在创建enum时加进去的。

7.3、ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始。

7.4、对应enum实例可以直接使用==比较,编译器会自动为你提供equals()和hashcode()方法。

7.5、我们也知道所有的enum都会继承自java.lang.Enum,因为java不支持多重继承,所以你的enum不能再继承其他类了。

enum EnumA extends ClassB{...}这是不行的。

7.6、enum还有一个非常有趣的特性,就是它允许你为enum实例编写方法,从而为每个enum实例赋予各自不同的行为。大致步骤就是在enum中定义抽象方法,然后每个实例都实现它。如下:

public enum EnumTest{

SHI_LI_ONE {

String getInfo(){

return "实例1";

}

},

SHI_LI_TWO {

String getInfo(){

return "实例2";

}

};

abstract String getInfo();

}

8.1、switch语句是可以没用default子句的,当表达式的值和所有值都不同时就退出了switch语句,继续执行后面的。

9.1、注解也被称之为元数据,它为我们在代码里添加信息提供了一种形式化的方法。注解的定义用@interface。例如:

public @interface Test{}

9.2、注解不支持继承,不能使用extends来继承某个@interface。

10.1、我们都知道static修饰的变量存放在方法区中,和类信息存放在一起,所以只有一份,可以用它来修饰作为多线程任务区分的标识ID,例如每创建一个任务就加1等。

Thinking in Java读书笔记相关推荐

  1. Java读书笔记(4)-多线程(二)

    Java读书笔记(4)-多线程(二) 2016-1-2 线程通信 传统的线程通信 Object类提供了wait(),notify()和notifyAll三个方法 适用情况:synchronized修饰 ...

  2. think in java 读书笔记 2 —— 套接字

    目录 think in java 读书笔记 1 --移位 think in java 读书笔记 2 -- 套接字 think in java 读书笔记 3 -- 数据报 概要 1. 套接字基本知识 2 ...

  3. Java读书笔记(8)-单例模式

    Java读书笔记(8)-单例模式 今天在阅读<Effective Java 2>第3条时,获知一种使用枚举enum实现单例模式的新方法,然而书上并没有就此展开深入说明,于是上网查阅了一些资 ...

  4. Effective Java读书笔记(二)

    Effective Java 读书笔记 (二) 创建和销毁对象 遇到多个构造器参数时要考虑使用构建器 创建和销毁对象 何时以及如何创建对象? 何时以及如何避免创建对象? 如何确保它们能够适时地销毁? ...

  5. head first java读书笔记

    head first java读书笔记 1. 基本信息 页数:689 阅读起止日期:20170104-20170215 2. 标签 Java入门 3. 价值 8分 4. 主题 使用面向对象的思路介绍J ...

  6. Effective Java 读书笔记(七):通用程序设计

    Effective Java 读书笔记七通用程序设计 将局部变量的作用域最小化 for-each 循环优于传统的 for 循环 了解和使用类库 如果需要精确的答案请避免使用 float 和 doubl ...

  7. #java读书笔记#面向对象2

    上一篇java读书系列笔记文章:#java读书笔记#面向对象1 14.Math类的使用(重点) (1)数学操作类:该类没有构造函数,方法均为静态的 (2)掌握内容 A:成员变量 **E:比任何其他值都 ...

  8. Effective Java读书笔记完结啦

    Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...

  9. Effective Java 读书笔记(一)

    前言: 开个新的坑位,<effective java>的读书笔记,之后有时间会陆陆续续的更新,读这本书真的感触满多,item01和item02就已经在公司的项目代码中看到过了.今天这篇主要 ...

  10. java开头流程_【java读书笔记】——java开篇宏观把控 + HelloWorld

    学完java有一段时间了,一直没有做对应的总结,总认为有一种缺憾.从这篇博客開始,将自己平时的学习笔记进行总结归纳,分享给大家. 这篇博客主要简单的介绍一下java的基础知识,基本的目的是扫盲.原来仅 ...

最新文章

  1. 让0球平局怎么算_半场16中5+0助攻+空气球,欧文威化,看看众美媒怎么说?
  2. .NET实现之(部署ActiveX控件—简)
  3. GBin1分享的10个吸引眼球的jQuery插件
  4. This dependency was not found: * !!vue-style-loader!css-loader?……解决方案
  5. 科目二、科目三易挂项目整理和网友支招
  6. linux 真实内存,Linux计算真实可用内存
  7. 数据--第46课 - 图算法课后练习
  8. setup_per_cpu_areas 函数
  9. 华为手机字体改简体_华为手机字体怎么更换简体
  10. 杨中科:【我的大学生活】
  11. Head First Java
  12. win10便签如何卸载?win10便签卸载和安装方法
  13. 如何利用光驱位给老旧笔记本电脑安装固态硬盘
  14. dipg(dip歌词翻译中文)
  15. Linux配置ntp时间同步
  16. 【Hive】left semi join(exists、in)和 left join 区别
  17. 史上最牛的Linux视频教程—兄弟连Linux笔记
  18. 【MySQL笔记】视图的创建与使用(VIEW)
  19. 云原生分布式 PostgreSQL+Citus 集群在 Sentry 后端的实践
  20. springCloud Alibaba seata 分布式事务

热门文章

  1. MS SQL入门基础:创建和使用约束
  2. filtic函数详解(附3个实例)
  3. matlab 电流相量图,表示了电路电压相量与电流相量之间的关系.ppt
  4. 多线程mute/lock_guard/unique_lock/condition_variable访问同一公共资源
  5. linux下设备树spi的节点查询,已解决: 关于ZYNQ-Linux中设备树SPI节点的疑问 - Community Forums...
  6. 【SpringBoot】 SpringBoot核心
  7. 考研数学预热(肖老师)-2019-12-21
  8. MySQL教程+视频
  9. java代码转python代码(需要手动调整)
  10. java swing 飞机大战游戏 github 免费 开源 公开 源码