Java编程思想第四版-知识盲点与精华

这些记下的内容大概就是普通程序员的一些盲点或者精华,需要更详细学习的话,建议买一本来看一看。

第一章 对象导论
1.容器即集合 List,Map,Set 以及队列、树、堆栈等。ArrayList中,随机访问元素花费固定的操作,但对于LinkedList来说,需要在列表移动,代价昂高。但在中间插入一个元素,那么LinkedList开销会比ArrayList小。

第二章 一切皆对象
1.new创建对象,对象保存在堆还是栈?
堆内存是用来存放由new创建的对象和数组,即动态申请的内存都存放在堆内存
栈内存是用来存放在函数中定义的一些基本类型的变量和对象的引用变量基本类型置于堆栈中,更加高效。其他java对象存储在堆中
2.永远不需要销毁对象,因为存在垃圾回收器
3.static可以只想为某特定域分配单一存储空间而不去考虑究竟要创建多少对象,甚至不需要创建任何对象,并且还可以在不跟任何包含它的类的任何对象关联在一起。这两句话的意思就是:即使没有创建对象,也能调用这个方法。

class StaticTest{
	static int i = 47;
}
StaticTest t1 = new StaticTest();// 等于StaticTest.i
StaticTest t2 = new StaticTest();// 也等于StaticTest.i

t1.i 与 t2.i都是只有一份存储空间,对于非static字段则对每个对象都有一个存储空间
为何称static为牧羊人?如果你的类代表羊,那么创建的若干的该类的对象,就好像创建了一个羊群,然而,类中的static方法就好比牧羊人一样,无论你的羊群中有多少只羊,而牧羊人只有一个。也就是说,static方法或属性与对象的创建无关,只和类有关。

第三章 操作符
1.Random在创建时,其会提供种子,该种子用于随机数生成器的初始化值,随机数生成器对于特定的种子值总是产生相同的随机数序列。
2.短路是与逻辑操作符相关的。

 a==b && a==c && b==3

当第一个结果为true ,表达式计算继续下去,然而第二个结果为false后,那么整个表达式就是false,所以不执行下去。
3.类型转换有两种 窄化转换与扩展转换。除了布尔型,其他基本类型都可转换。
4.提升:如果对基本数据类型执行算术运算或按位运算,只要类型比int小(如char,byte,short),在运算之前,这些值自动转换成int。如果想把结果赋值给较小的类型,就必须使用类型转换(既然把结果赋给了较小的类型,就可能出先信息丢失)。通常表达式中出现的最大的数据类型决定了表达式最终结果的数据类型,如果将一个float值与一个double值进行相乘。结果就是double,如果int与long相加,结果为long

第四章 控制执行流程
1.switch可以于enum枚举来进行使用

第五章 初始化与清理
1.用this调用一个构造器的时候,必须将构造器调用置于最起始处,不然编译器会发生报错
2.在static方法的内部不能调用非静态方法,但是非静态方法的内部能调用static方法
3.不要过多地使用finalize(),它确实不是进行普通地清理工作的合适场所。
4.java虚拟机采用自适应的垃圾回收技术,一种做法名为停止-复制。也就是先暂停程序运行,然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾。但这种所谓的“复制式回收器”效率会降低。因为有两个堆之间陶腾,维护的时间比实际多一倍。为了避免这种情况,java虚拟机会进行检查,要是没有新垃圾产生,就转换成另一种工作模式(“自适应”),称为标记-清扫。在这里插入图片描述在这里插入图片描述
5.尽管没有显式地使用static关键字,构造器实际上也是静态方法。
6.enum有一个特别使用地特性,就是它可以在switch语句内使用

public class test {
    Spiciness degree;
    public void describe(){
        switch (degree){
            case HOT:;
            case MEDIUM:;
            case MILD:;
            case NOT:;
            case FLAMING:;
        }
    }
}

第六章 访问权限控制
1.调试功能在开发中开启的,在发布的产品中是禁止的。

第七章
1.@Override注解可以防止你在不想重载时而意外进行x
2.protect,但在实际项目中,经常会想要将某些事物尽可能对这个世界隐藏起来,但仍然允许导出类的成员访问它们。
3.Final对于基本类型,是一段不能改变的存储空间,但是对于对象引用,是让引用恒定不变,一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象,这是final对对象的作用,但是对象其自身却是可以被修改的,java并没有提供使任何对象恒定不变的途径,就比如是数组,当static final int[] a = new int[] {1,2,3,4}; a[1] = 3;这使得a[1]真的变成了3。
4.注意,带有恒定初始值的final static基本类型全用大写字母命名,并且字与字之间用下划线隔开。
5.java允许生成“空白final”,所谓的空白final 就是private final int j;但是必须在域的定义处或者每个构造器中用表达式对fina进行赋值,这正是final域在使用前总是被初始化的原因所在。

第八章 多态
1.多态的实现离不开动态绑定,先举个多态的例子。

public class Music {
    public static void tune(Instrument i){
        i.play();
    }
    public static void main(String[] args) {
        Wind f =  new Wind();
        tune(f);
    }
}
public class Instrument {
	@Override
    public void play() {
        System.out.println("Wind");
    }
}

这里看出,明明tune方法引用的是Instrument,但是可以传入Wind,是因为进行了继承,这就是向上转型。那么有读者说,那我直接弄一个方法如下:

public static void tune(Wind i){
        i.play();
    }

不就好了吗。那么问题来了,如果我再增多点乐器,比如吉他,钢琴,那么不就要写很多个方法了吗?那么如果直接用基类Instrument的话,那传入参数,编译器会知道是哪种乐器吗?它不知道。多态是一项让程序员”将改变的事物与未变的事物分离开来“的重要技术。
2.动态绑定:将一个方法调用同一个方法主体关联起来被称作为绑定。若再程序执行前进行绑定,这叫做前期绑定。那么后期绑定就是:在运行的时候,根据对象的类型进行绑定。这个后期绑定也叫做动态绑定

Instrument i = new Wind();
        i.play();

在编译时,编译器不需要获得很合特殊信息就能进行正确的调用,对于paly()方法的所有调用都是通过动态绑定进行的。贴入书本上的代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此份代码意思是随机生成数字存入数组中,然后按照随机数组创建不同的对象。每一次循环调用的对象不同,但是它们的基类都是Shape,
对象分别是

 Shape s1 = new Circle(); 
 Shape s2 = new Square(); 
 Shape s3= new Triangele();

3对于Private方法,会被编译器自动认为是final方法,对于子类是屏蔽的,所以不能被子类重载,因此得出结论是:只有非private方法才可以被覆盖;但是还需要密切
关注覆盖private方法的现象,这时候虽然编译器不会报从,但是也不会按照我们所期望的来执行。确切地说,在导出类中,对于基类中的private,最好采用不同的名字。
4.如果一个方法是静态的,那么它的行为就不具有多态性。
5.“用继承表达行为间的差异,并用字段表达状态上的变化”。

第九章 接口
1.完全解耦,如果你想要一个方法应用于不在此继承结构中的某个类,那么接口就能帮助你。

第十章 内部类
1.如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须像main()方法中那样,具体地指明这个对象的类型:OuterClassName.InnerClassName。
2.普通内部类的字段与方法,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类,但是嵌套类可以包含所有这些东西。
3.在接口内不能放置任何代码,但是嵌套类却可以作为接口的一部分,但是这类必须是Public和stati。
4.使用内部类的原因是,每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多重继承的解决方案变得完整,接口解决了部分问题,而内部类有效实现了“多重继承”。所以就有一种情形,必须在一个类中以某种方式实现两个接口,你有两种选择,一是使用单一类,二是使用内部类。其实这两种做法都可以,但是如果拥有的是抽象的类或者具体的类,而不是接口,那么只能使用内部类才能实现多重继承。
5. 内部类也会生成.class文件已包含它们的Class对象信息。格式:外围类的名字$内部类名字.class

第十一章 持有对象
1.Arrays.asList()方法接收一个数组或是一个用逗号分隔的元素列表并将其转换成一个List对象。
2.Collections.addAll()方法接收一个Collection对象,以及一个数组或是一个用逗号分割的列表, 将元素添加到Collection中。
3.Collection.addAll()成员方法只能接收另一个Collection对象作为参数。
4.Collection打印出来的是用方括号括住,而Map使用大括号括住的。
5.Collections.reverseOrder()产生范旭的Comparator
6.Arrays.asList()的输出被传递给了ArrayList()的构造器,这将创建一个引用ia的元素的ArrayList,这样如果使用Collections.shuffle是不会改变该数组的,如果直接使用Arrays.asList(ia),那么就会打乱ia的顺序

第十二章 通过异常处理错误
1.可以使用java.util.logging工具将输出记录到日志中。
在这里插入图片描述
2.无论异常是否抛出,finally子句总能被执行,就算涉及到break与continue语句的时候,finalliy子句也会得到执行,这也同事看出,在finally类内部,从何处返回无关紧要,它还是会执行。finally非常重要,它能使程序员保证,无论try块里无论发生什么,内存总能得到释放,所以当要把除内存之外的资源恢复到它们的初始状态, 就要用到finally自居,比如已经打开的文件或者网络连接,xx.close();

第十三章 字符串
1.String对象具有只读特训表格,所以指向它的任何引用都不可能改变它的值。
2.String.equalsIgnoreCase() 忽略大小写比较两个String内容是否相同
3.String.trim() 将String两端的空白字符删除后,返回一个新的String对象。
4.正则表达式(关于正则表达式,建议去搜其他博主,他们有更通俗易懂的方法和教学)
\d代表一位数字、\意思是->我要插入一个正则表达式的反斜线所以其后的字符具有特殊的意义。所以如果想要表达一位数字那么正则表达式应该是\d。如果插入一个普通的反斜线,则\\,不过换行和制表符之类的东西只需要使用单反斜线:\n\t。要表示“一个或者多个之前的表达式”,应该使用+,所以表示“可能有一个符号后面跟着一位或者多位数字” -?\d+

在这里插入图片描述
第十四章 类型信息
1.Class对象仅在需要的时候才被加载,static初始化是在类加载时进行的。
Class.forName()是取得Class对象的引用的一种方法。
2.为了使用类而做得准备工作实际包含三个步骤:

  1. 加载,这是由类加载器执行的。该步骤将查找字节码,并从这些字节码中创建一个Class对象。通常在classpath所制定的路径中查找,但这并非是必须的。
  2. 链接。在链接阶段将验证类中的字节码,为静态与分配存储空间,并且如果必须的话,将解析这个类创建的对其他类的所有引用。
  3. 初始化。如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块。初始化被延迟到了对静态方法或者非常数静态与进行首次引用才会被执行,构造器隐式地是静态的。

3.仅使用.class语法来获得对类的引用就不会引发初始化。但是为了产生Class引用,Class.forName()立即就进行了初始化。
4.instanceof返回一个布尔值,告诉我们对象是不是某个特定类型的实例在这里插入图片描述
第十五章 泛型 建议认真看,都是重点

第十六章 数组
1.Arrays.deepToString()将多位数组转换为多个String
在这里插入图片描述
2.这是使用参数化方法而不适用参数化类的方便之处,你不必为需要应用的每中不同的类型都使用一个参数去实例化这个类。↓
3.Arrays.fill()填充数组各个位置。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值