Java 易混,重难点汇总

1.基础篇

整型

浮点

final 一般用于指示常量,即变量只能被赋值一次。一旦被赋值,就不能更改了。(即没有set方法)命名规则一般使用全大写及下划线。
类常量(外部类字段) 在一个类的多个方法中使用,位于main方法的外部。一般用 static final。声明为public时,其他类(内部类)的方法也可以使用该变量。
尽量不要强制转换boolean类型,可以使用条件表达式(三元操作符)b?1:0
static 可以理解为一份拷贝 相当于在某段时期是不会变化。直到静态常量被重新赋值。

自增与自减运算符

前缀 ++n 后缀 n++ 前缀形式会先完成加1;而后缀形式会使用变量原来的值。

构建字符串

多个较短的字符串构建字符串可以用以下方法:

StringBuilder builder = new StringBuilder();
builder.append(ch);
builder.append(str);
String completedString = builder.toString();

注:substring(a,b)的长度为b-a。
注:continue语句越过了当前循环体的剩余部分(未循环的部分),立刻跳到循环首部。
注:String[] args 即为命令行参数
注:String 是一组char[],因此==用来比较char下标,是否放置在同一个位置上
注:break 终止循环 continue是跳过本次循环(第i次执行被跳过)

新建变量

新建变量时,应该进行初始化操作,系统在运行过程不会对变量进行初始化。有报错的风险。

日期

一般而言,创建一个Date() 对象,所显示的时间格式并不符合中国时间格式,可用LocalDate()对象,但是不常用。
注:HH是24小时制,hh是12小时制
区别就是:大写的H是二十四小时制的小时数(0-23),小写的h是十二小时制的小时数(am/pm 1-12)
Java里面MM表示月 mm表示分钟 HH表示 24小时制 hh表示12小时制
Oracle里面 mm表示月 mi表示分钟 hh24表示小时
mm与m等,它们的区别为是否有前导零:H,m,s表示非零开始,HH,mm,ss表示从零开始。
比如凌晨1点2分,HH:mm显示为01:02,H:m显示为1:2。

构造器

构造器与类同名。 在构造类的对象时,构造器将实例化对象。
注: 预定义类是不需要初始化数据 因为没有数据
使用对象,需要先构造对象,指定初始化状态。

访问器和修改器

访问对象字段和修改对象字段的方法

隐式参数与显式参数

隐式参数是调用方法的目标(该类的字段),param = this.paramthis指向的是隐式对象。
为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
显式参数 方法名接收的参数就是显式参数。

实参与形参

实际存在的值 type param = 12; 为实参,public void method(type param...) param 为形参
java只有按值调用,即值传递。方法参数接收的是调用者提供的数据。是因为java对于数据的操作,是对该数据的备份的操作。
int a = 10;int y = 0;y=a; a =y; int a = 10 还是10 是不会变的。

对象

对象的行为 对对象施加的操作
对象的状态 施加操作之后,对象的响应
对象标识 相同的行为与状态的对象
构造方法 可以先设计字段,再根据字段关系,给类添加相应的方法。
工厂方法——java 自带类型线程池等类,可以通过实例化一个工厂类,对工厂类赋值,达到创建对象的目的。

对象克隆

原变量和副本都是同一个对象的引用,任何一个变量改变都会影响另一个变量。
因此被拷贝的对象的字段必须是不可变的,避免出现共享不安全的现象。
浅拷贝 指只拷贝不可变字段,即拷贝的字段是基本类型。
深拷贝 可变字段或者不可克隆的字段

可变对象与不可变对象

区分方法:其他内部值是否能改变。
可变对象
创建一个对象:
StringBuilder sb = new StringBuilder("a");
sb.append(“b”); //此时对象sb已经变化了 即sb的指向发生变化,不再指向a,而是b。
不可变对象
String a = "aaaaa";
静态方法 即可以不用实例出一个对象,可直接调用。一般用className.staticMethod()方式调用。例如 main()

对象关系

依赖 一个类的方法操纵另一个类的对象 例:订单(Order)需要访问Account对象查看信用状态。
关联 一个对象包含一些对象 例:订单(Order)包含一些物品(Item)对象
继承 extend 继承方法

数据私有
数据初始化
不使用过多的基本类型
不是每个字段都需要get、set方法
不应该过多分解类
类名和方法名体现职责
优先使用不可变类

内部类

内部类(inner class)是定义在另一个类中的类
● 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据。理解成这样就行
● 内部类可以对同一个包中的其他类隐藏起来。
● 当想要定义一个回调函数且不想编写大量代码时,使用匿名(anonymous)内部类比较便捷。
作用:一个方法可以引用调用这个方法的对象数据域。内部类既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域。
只有内部类可以是私有类,而常规类只可以具有包可见性,或公有可见性。
构造器语法

内部类中声明的所有静态域都必须是final。原因很简单。我们希望一个静态域只有一个实例,不过对于每个外部对象,会分别有一个单独的内部类实例。如果这个域不是final,它可能就不是唯一的。内部类不能有static方法。

局部内部类

局部类不能用public或private访问说明符进行声明。它的作用域被限定在声明这个局部类的块中。
它们不仅能够访问包含它们的外部类,还可以访问局部变量。不过,那些局部变量必须事实上为final。这说明,它们一旦赋值就绝不会改变。

匿名内部类(实现事件监听器和其他回调)

假如只创建这个类的一个对象,就不必命名了。这种类被称为匿名内部类(anonymous inner class)。
双括号初始化写法 {{}}
对于匿名子类 通过反射判断equals方法会失败

>
由于构造器的名字必须与类名相同,而匿名类没有类名,所以,匿名类不能有构造器

静态内部类

使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类对象。为此,可以将内部类声明为static,以便取消产生的引用。
前面例子中所使用的内部类不同,在Pair对象中不需要引用任何其他的对象,为此,可以将这个内部类声明为static

静态内部类的对象除了没有对生成它的外围类对象的引用特权外,与其他所有内部类完全一样

继承

基于已存在的类构造一个新类。继承已存在的类,即继承已存在类的方法和字段(域)。
场景:经理(Manager)的待遇与普通雇员(Employee)的待遇存在差异,也存在着很多相同的地方,经理可以在领取薪水的同时,在完成了预期的业绩之后还能得到奖金。Manager可以继承Employee中的属性和方法,再增加新功能。
使用 关键字extends表示继承
超类、基类或父类;子类、派生类或孩子类;
每个类只能有且只有一个超类,可以实现多个接口。所以只能是 class Employee extends Person (一个)
这是接口概念引入的原因。java不支持多继承,但是可以实现接口。多继承会导致语言逻辑复杂化。
1将公共操作和字段放在父类
2不要使用protected字段
3子类继承父类,不要过多的继承,导致代码耦合度过高
4重载方法不要改变该方法的作用

继承实例


泛型(类的概念)


泛型类(类工厂)

泛型类可以有多个类型变量。

T限制为实现了Comparable接口(只含一个方法compareTo的标准接口)的类。可以通过对类型变量T设置限定(bound)实现这一点:

泛型方法

类型变量的限定



Comparable接口是一个泛型类型。
类可以多个接口超类型但是继承只能一个类。

类型擦除

不能用类型参数代替基本类型,即只有List<String>
原始类型用第一个限定的类型变量来替换,如果没有给定限定就用Object替换。例如,类Pair<T>中的类型变量没有显式的限定,因此,原始类型用Object替换T。

多态情境下的擦除

强制类型转换
<T>是不能用instanceof 进行比较的,也不能实例化,即new T(…), new T[…]或T.class

通过反射调用Class.newInstance方法来构造泛型对象,泛型数组,泛型类也引用不了类型变量,泛型类不能用于try...catch语句,但是可以使用泛型变量。

泛型的继承规则

是接口继承,跟T无关;ArrayList<T>类实现List<T>接口
涉及到通配符,允许类型参数变化

表示任何泛型Pair类型,它的类型参数是Employee的子类,如Pair<Manager>,但不是Pair<String>
通配符的超类型限定 ? super Manager


无限定通配符 Pair<?> 不如直接用 Pair<T>来的安全

可以用任意Object对象调用原始Pair类的setObject方法。

泛型Class类


Employee.class是类型Class的一个对象。

重载方法

通过继承父类的方法名,在要用super,不然就会之前一样系统防止重名,使用this,将会陷入无限调用自己,以至于陷入死循环。并且作用域从private 改为public
super若没有特别说明,默认没有参数的构造器。必须在子类的第一条语句,即紧挨字段下方。
代码

    public class Employee {public double getSalary(){.....}}public class Manager extends Employee{public double getSalary(){double baseSalary = super.getSalary();return baseSalary + bonus;}}

当e引用Employee对象时,e.getSalary( )调用的是Employee类中的getSalary方法;当e引用Manager对象时,e.getSalary( )调用的是Manager类中的getSalary方法。称之为多态

对象包装器与自动装箱

Integerint的包装器。为final值。
添加 :

ArrayList<Integer> list = new ArrayList <Integer> ;
list.add(3) 自动装箱为 list.add(Integer.valueOf(3));

Integer对象是不可变的:包含在包装器中的内容不会改变。不能使用这些包装器类创建修改数值参数的方法。

参数数量可变的方法

public static void main(String[] args) 其中args 的参数数量可变
等同于 public static void main(String... args)

枚举类型

所有的枚举类型都是Enum类的子类,常用方法:toString、valueOf、values

反射(不可过多使用)

Class类

Object类中的getClass()方法将会返回一个Class类型的实例。eg:java.lang.String
最常用的Class方法是getName。这个方法将返回类的名字
调用静态方法forName获得类名对应的Class对象。只有在className是类名或接口名时才能够执行
一个Class对象实际上表示的是一个类型,而这个类型未必一定是一种类。例如,int不是类,但int.class是一个Class类型的对象。
newInstance(),可以用来动态地创建一个类的实例,newInstance(),可以用来动态地创建一个类的实例(所谓的实例化)
Array类中的静态方法newInstance,它能够构造新数组。在调用它时必须提供两个参数,一个是数组的元素类型,一个是数组的长度。

利用反射分析类的能力

java.lang.reflect包中有三个类Field、Method和Constructor分别用于描述类的域、方法和构造器。
getModifiers的方法,它将返回一个整型数值,用不同的位开关描述public和static这样的修饰符使用状况。
java.lang.reflect包中的Modifier类的静态方法分析getModifiers返回的整型数值。例如,可以使用Modifier类中的isPublic、isPrivate或isFinal判断方法或构造器是否是public、private或final
Class类中的getFields、getMethods和getConstructors方法将分别返回类提供的public域、方法和构造器数组,其中包括超类的公有成员。Class类的getDeclareFields、getDeclareMethods和getDeclaredConstructors方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护成员,但不包括超类的成员。
反射机制的默认行为受限于Java的访问控制。然而,如果一个Java程序没有受到安全管理器的控制,就可以覆盖访问控制。为了达到这个目的,需要调用Field、Method或Constructor对象的setAccessible方法。例如,

调用f.set(obj, value)可以将obj对象的f域设置成新值。(因为通过反射拿到的字段值是对象,而没有数据类型。)
ObjectAnalyzer将记录已经被访问过的对象

高级篇

接口

接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。

接口可以看做是没有字段的抽象类。但是接口不是类,不能使用new运算符实例化一个接口。
可以使用instanceof检查一个对象是否属于某个特定的接口。
接口也可以继承。但是不能包含字段或者静态方法,可以包含常量
命名以及参数类型尽量不要重复,防止冲突
如果方法名冲突,父类接口优先级比子类接口优先级高 —“类优先”

接口与回调(**)

回调(callback)是一种常见的程序设计模式。在这种模式中,可以指出某个特定事件发生时应该采取的动作。例如,可以指出在按下鼠标或选择某个菜单项时应该采取什么行动。然而,由于至此还没有介绍如何实现用户接口,所以只能讨论一些与上述操作类似,但比较简单的情况。

lambda表达式(函数式编程)



函数式接口(延迟执行)

对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口

表达式System.out::println是一个方法引用(method reference),它等价于lambda表达式x -> System.out.println(x)
object::instanceMethod
Class::staticMethod
Class::instanceMethod
superClass::instanceMethod
this::instanceMethod
int[]::new是一个构造器引用,它有一个参数:即数组的长度。这等价于lambda表达式x -> new int[x]
Java有一个限制,无法构造泛型类型T的数组。表达式new T[n]会产生错误,因为这会改为new Object[n]

变量作用域

lambda表达式的数据结构存储自由变量的值,为闭包。
()->{闭包} 闭包的值是不能被改变的。lambda表达式中捕获的变量必须实际上是最终变量(effectively final)。指这个变量初始化之后就不会再为它赋新值。
在lambda表达式中声明与一个局部变量同名的参数或局部变量是不合法的。

在一个lambda表达式中使用this关键字时,是指创建这个lambda表达式的方法的this参数
如果想要立即执行代码,完全可以直接执行,而无需把它包装在一个lambda表达式中。之所以希望以后再执行代码

代理(不确定接口实现场景)

有一个表示接口的Class对象(有可能只包含一个接口),它的确切类型在编译时无法知道。这确实有些难度。要想构造一个实现这些接口的类,就需要使用newInstance方法或反射找出这个类的构造器。但是,不能实例化一个接口,需要在程序处于运行状态时定义一个新类。
这里借用反射 获取接口的参数与方法名 根据二分法查找到目标接口。代理起到的作用就是在接口被调用的时候,即运行时,将接口与方法调用结合起来。
即代理类是在程序运行过程中创建的。
所有的代理类都扩展于Proxy类。一个代理类只有一个实例域——调用处理器,它定义在Proxy的超类中。
代理类一定是publicfinal
可以通过调用Proxy类中的isProxyClass方法检测一个特定的Class对象是否代表一个代理类。

异常处理

异常分类

一个方法必须声明所有可能抛出的受查异常,而非受查异常要么不可控制(Error),要么就应该避免发生(RuntimeException)。如果方法没有声明所有可能发生的受查异常,编译器就会发出一个错误消息。
由于父类中方法没有抛出任何异常,所以,子类也不能抛出任何受查异常
1)找到一个合适的异常类。
2)创建这个类的一个对象。
3)将对象抛出。

捕获异常

将可能抛出已检查异常的一个或多个方法调用代码放在try块中,然后在catch子句中提供处理器代码。

如果类名不存在,则将跳过try块中的剩余代码,程序直接进入catch子句
要想捕获一个异常,必须设置try/catch语句块

捕获那些知道如何处理的异常,而将那些不知道怎样处理的异常继续进行传递。
如果想传递一个异常,就必须在方法的首部添加一个throws说明符,以便告知调用者这个方法可能会抛出异常。
不允许在子类的throws说明符中出现超过超类方法所列出的异常类范围。

finally子句

不管是否有异常被捕获,finally子句中的代码都被执行

1)代码没有抛出异常。执行标注的1、2、5、6处。
2)抛出一个在catch子句中捕获的异常。在上面的示例中就是IOException异常。在这种情况下,程序将执行try语句块中的所有代码,直到发生异常为止。此时,将跳过try语句块中的剩余代码,转去执行与该异常匹配的catch子句中的代码,最后执行finally子句中的代码。如果catch子句没有抛出异常,程序将执行try语句块之后的第一条语句。在这里,执行标注1、3、4、5、6处的语句。如果catch子句抛出了一个异常,异常将被抛回这个方法的调用者。在这里,执行标注1、3、5处的语句。
3)代码抛出了一个异常,但这个异常不是由catch子句捕获的。在这种情况下,程序将执行try语句块中的所有语句,直到有异常被抛出为止。此时,将跳过try语句块中的剩余代码,然后执行finally子句中的语句,并将异常抛给这个方法的调用者。在这里,执行标注1、5处的语句。try语句可以只有finally子句,而没有catch子句
注:建议解耦合try/catch和try/finally语句块。
1.只在异常情况下使用异常机制,因为捕获异常非常耗时。
2.尽量不要写多个try语句,可以有多个catch捕获语句
3.选对合适的异常

分析堆栈轨迹元素
基本日志

用一个静态变量存储日志记录器的一个引用,防止被垃圾回收


集合(接口)

队列Queue<E>:“先进先出”原则,
如果需要一个循环数组队列,就可以使用ArrayDeque类,是有界集合。循环数组要比链表更高效
如果需要一个链表队列,就直接使用LinkedList类,这个类实现了Queue接口。如果程序中要收集的对象数量没有上限,就最好使用链表来实现。
Collection接口(不允许有重复对象)
Iterator接口 next方法可以逐个访问集合中的每个元素。

List是有序集合

并发

一个程序同时执行多个任务。通常,每一个任务称为一个线程(thread),它是线程控制的简称。可以同时运行一个以上线程的程序称为多线程程序(multithreaded)。
调用Thread.sleep不会创建一个新线程,sleep是Thread类的静态方法,用于暂停当前线程的活动。

线程

  1. Runnable接口的run方法

    2.由Runnable创建一个Thread对象
锁对象


关键词 synchronized

Java 核心技术卷一 随笔相关推荐

  1. Java核心技术卷一读书笔记

    文章目录 Java核心技术卷一读书笔记 第一章 Java程序设计概述 1.1 关键特性 第二章 Java程序设计环境 2.1 使用命令行工具 第三章 Java的基本查询设计结构 3.1 数据类型 3. ...

  2. Java核心技术卷一基础知识第10版demo实例

    Java核心技术卷一基础知识第10版demo实例 第三章 JAVA的基本程序设计结构 3.7输入与输出 3.7.1读取输入 3.8控制流程 3.8.3循环 3.10数组 3.10.6多维数组 第四章 ...

  3. Java核心技术卷一 -第十二章:多线程

    系列文章目录 Java核心技术卷一 -第一章:java"白皮书"的关键术语 Java核心技术卷一 -第三章:数据类型 Java核心技术卷一 -第三章:变量与常量 Java核心技术卷 ...

  4. Java核心技术卷一 -第九章:集合

    系列文章目录 Java核心技术卷一 -第一章:java"白皮书"的关键术语 Java核心技术卷一 -第三章:数据类型 Java核心技术卷一 -第三章:变量与常量 Java核心技术卷 ...

  5. Java核心技术卷一 -第四章:方法参数

    系列文章目录 Java核心技术卷一 -第一章:java"白皮书"的关键术语 Java核心技术卷一 -第三章:数据类型 Java核心技术卷一 -第三章:变量与常量 Java核心技术卷 ...

  6. Java核心技术卷一笔记

    Java核心技术-卷一学习笔记 文章目录 Java核心技术---卷一学习笔记 前言 一.第一章Java程序设计 标题Java具有的特性: 二.第二章Java程序设计环境 JDK和Jre的区别 第三章J ...

  7. Java核心技术卷一、二读书笔记(PDF)分享

    分享一下笔记(书)PDF在下面,懂得都懂 一 Java程序设计概述 1)Java语言的特性 简单性 Java语法是c++的一个纯净版本,这里没有头文件,指针运算(指针语法),结构,联合,操作符重载,虚 ...

  8. Java核心技术卷一 -第五章:装箱和拆箱

    系列文章目录 Java核心技术卷一 -第一章:java"白皮书"的关键术语 Java核心技术卷一 -第三章:数据类型 Java核心技术卷一 -第三章:变量与常量 Java核心技术卷 ...

  9. 《Java核心技术卷一》读书笔记

    <Java核心技术卷一>读书笔记 对象与类 类 类是构造对象的模板.蓝图.由类构造对象的过程称为类的实例. 对象的数据叫做实例域,操作数据的过程叫做方法 对于每个特定的类实例(对象)都要一 ...

最新文章

  1. 【廖雪峰Python学习笔记】函数式编程
  2. MSB3721 命令““C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\bin\nvcc.exe“ 已退出 返回代码为1
  3. 深度学习基础(十二)—— ReLU vs PReLU
  4. 【正一专栏】谁能阻止超神的曼城
  5. Fiddler抓包工具详解(三)(fiddler监控面板+辅助工具)
  6. Boost::context模块callcc的分段的测试程序
  7. codeforces 689B Mike and Shortcuts 最短路
  8. 分金币 Uva 11300
  9. 拼多多回应“二次上市”:公司现金储备充裕 暂无任何计划
  10. 移动端ios和安卓input问题
  11. IIS发布网站遇到的异常
  12. 海康威视摄像头web端播放
  13. 等价类划分法设计测试用例
  14. Excel游戏—制作数字炸弹小游戏
  15. 乒乓球十一分制比赛规则_乒乓球比赛规则、技术及知识
  16. 从辉煌走向消亡(上)——小型机之王DEC公司
  17. PHP自学---黑马程序员笔记【持续更新】
  18. linux hairpin mode
  19. Uos统信系统 SSH
  20. php办公oa系统带流程审批支持手机版wap源码

热门文章

  1. 阿里、百度、华为:中国智能城市马拉松赛道上的三个技术高度
  2. java狗具有特别的接飞盘的方法_经验分享:狗狗接飞盘的训练方法
  3. 高空坠球-皮球从某给定高度自由落下
  4. HTTP 中的 Cookie
  5. node离线安装(linux环境)
  6. 控制台信息在生产环境不打印
  7. 博客园博客如何使用模板
  8. 诗经 - 小雅 - 皇皇者华
  9. 我和王争学设计模式|桥接模式
  10. 用Vue实现购物车组件