一、基础知识
1. JVM、JRE和JDK的区别
JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性。
JRE(Java Runtime Environment):java的运行环境,包括jvm+java的核心类库。
JDK(Java Development Kit):java的开发工具,包括jre+开发工具。
Java语言是跨平台,jvm不是跨平台的。
2. 环境变量path和classpath的作用是什么?
- path是配置Windows可执行文件的搜索路径,即扩展名为.exe的程序文件所在的目录,用于指定DOS窗口命令的路径。
- classpath是配置class文件所在的目录,用于指定类搜索路径,JVM就是通过它来寻找该类的class类文件的。
3. 变量有什么用?为什么要定义变量?什么时候用?
- 变量的作用:用来存储数据。
- 为什么要定义变量:用来不断的存放同一类型的常量,并可以重复使用。
4. &和&&的区别?
- &&会出现短路,如果可以通过第一个表达式判断出整个表达式的结果,则不继续后面表达式的运算;只能操作boolean类型数据。
- &不会出现短路,将整个表达式都运算。既可以操作boolean数据还可以操作数。
5. 标示符命名规则
- 由数字(0-9),大小写英文字母,以及_和$组成。
- 不能以数字开头。
- 不能使用关键字来自定义命名。
6. 数据类型
- 基本数据类型(4类8种)
(1)整数类型:byte、short、int、long
(2)浮点数类型:float、double
(3)字符类型:char
(4)布尔类型:boolean(ture false)- 引用数据类型
(1)类
(2)接口
(3)数组
7. 类型转换
精度从低到高 byte short(char) int long float double
- 自动类型转换 将一个低精度--->高精度
- 强制类型转换 将一个高精度--->低精度(精度会下降)
8. 有符号数据的表示法(原码-反码-补码)
原码,反码(原码取反),补码(反码+1)。
9. 函数
- 定义
函数就是定义在类中的具有特定功能的一段独立小程序。- 特点
(1)定义函数可以将功能代码进行封装。
(2)便于对该功能进行复用。
(3)函数只有被调用才会被执行。
(4)函数的出现提高了代码的复用性。
(5)对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。- 函数的应用两个明确
(1)明确要定义的功能最后的结果是什么?
(2)明确在定义该功能的过程中,是否需要未知内容参与运算。
10. 重载
概念:在同类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
特点:与返回值类型无关,只看参数列表(参数类型以及参数个数)。
好处:方便于阅读,优化了程序设计。
11. 数组
概念:同一种数据类型的集合。
好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。
12. 内存结构
- 栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。
- 堆内存:数组和对象,通过new建立的实例都存放在堆内存中。
- 方法区:静态成员、构造函数、常量池、线程池。
- 本地方法区:window系统占用。
- 寄存器。
二.面向对象
1. 面向对象思想
- 概述
面向对象是相对于面向过程而言的,面向过程强调的是功能,面向对象强调的是将功能封装进对象, 强调具备功能的对象。- 思想特点
(1)是符合人们思考习惯的一种思想。
(2)将复杂的事情简单化了。
(3)将程序员从执行者变成了指挥者。
比如:我要达到某种结果,我就寻找能帮我达到该结果的功能的对象,如我要洗衣服我就买洗衣机,至于怎么洗我不管。- 特征
(1)封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式。
(2)继承: 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
(3)多态: 一个对象在程序不同运行时刻代表的多种状态,父类或者接口的引用指向子类对象。
2. 类和对象
类:对现实世界中某类事物的描述,是抽象的,概念上的定义。
对象:事物具体存在的个体。
3. 成员变量和局部变量的区别(重点)
- 作用域
成员变量:针对整个类有效。
局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)- 存储位置
成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。- 初始值
成员变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值。
4. 匿名对象
- 匿名对象就是没有名字的对象。是对象的一种简写形式。
- 应用场景
(1)只调用一次类中的方法。
(2)可以作为实际参数在方法传递中使用。
5. 封装
指隐藏对象的属性和实现细节,仅对外提供公共访问方式;比如电脑机箱、笔记本等。
好处:
将变化隔离;方便使用;提高复用性;提高安全性。
6. 关键字private
封装代码的一种体现
- 私有的意思,权限修饰符。
- 用来修饰成员变量和成员函数。
- 用private修饰的成员只在本类中有效。
- 私有是封装的一种体现。
7. 构造方法
- 构造方法特点
(1)方法名与类名相同。
(2)没有返回类型。
(3)没有返回值。- 构造方法作用
构造函数是用于创建对象,并对其进行初始化赋值,对象一建立就自动调用相对应的构造函数。- 构造方法的注意事项
(1)如果一个自定义类没有构造方法,系统会默认给出一个无参构造方法。
(2)如果一个自定义类提供了构造方法,那么,系统将不再给出无参构造方法。这个时候,你可以不使用无参构造方法。如果你想使用,那么,就必须手动给出无参构造方法。
建议:一般情况下,我们的自定义类都要手动给出无参构造方法。- 构造方法和成员方法的区别
(1)格式区别
a:构造方法和类名相同,并且没有返回类型,也没有返回值。
b:普通成员方法可以任意起名,必须有返回类型,可以没有返回值。
(2)作用区别
a:构造方法用于创建对象,并进行初始化值。
b:普通成员方法是用于完成特定功能的。
(3)调用区别
构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数。普通成员方法是由创建好的对象调用,可以调用多次。
8. 构造代码块
- 构造代码块作用
给对象进行初始化,对象一建立就执行,而且优先于构造函数执行。- 构造代码块和构造函数的区别
(1)构造代码块是给所有不同对象的共性进行统一初始化。
(2)构造函数是给对应的对象进行初始化。
9. this关键字
- this关键字代表本类对象的一个引用,谁调用this所在的方法,this就代表谁。
- this的使用场景
(1)用于区分同名成员变量和局部变量。
(2)在定义函数时:该函数内部要用到调用该函数的对象时,因为此时对象还没建立,故this代表此对象。
(3)构造函数间调用:这个时候,this(参数)必须作为第一条语句存在。
10. Person p = new Person();在内存中做了哪些事情
- 将Person.class文件加载进内存中。
- 如果p定义在主方法中,那么,就会在栈空间开辟一个变量空间p。
- 在堆内存给对象分配空间。
- 对对象中的成员进行默认初始化。
- 对对象中的成员进行显示初始化。
- 调用构造代码块对对象进行初始化。(如果没有就不执行)
- 调用构造方法对对象进行初始化。对象初始化完毕。
- 将对象的内存地址赋值给p变量,让p变量指向该对象。
11. static关键字
- 静态的意思
用来修饰成员变量和成员函数。- 静态的特点
(1)随着类的加载而加载。
(2)优先于对象存在。
(3)对所有对象共享。
(4)可以被类名直接调用。- 静态的注意事项
(1)静态方法只能访问静态成员,为什么?
因为静态的内容是随着类的加载而加载,它是先进内存的。
(2)静态方法中不能使用this,super关键字。
(3)主方法是静态的。
public static void main(String[] args)
public:公共的意思,是最大权限修饰符。
static:由于jvm调用main方法的时候,没有创建对象。只能通过类名调用。所以,main必须用static修饰。
void:由于main方法是被jvm调用,不需要返回值。用void修饰。
main:main是主要的意思,所以jvm采用了这个名字。是程序的入口。
String[]:字符串数组。
args:数组名;在运行的时候,通过java命令给args数组赋值。
格式:java MainTest hello world itcast- 静态变量和成员变量的区别
(1)调用方式
a:静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用,这个变量属于类。
b:成员变量也称为实例变量,只能通过对象名调用。这个变量属于对象。
(2)存储位置
a:静态变量存储在方法区长中的静态区。
b:成员变量存储在堆内存。
(3)生命周期
a:静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
b:成员变量随着对象的创建而存在,随着对象的消失而消失。
(4)与对象的相关性
a:静态变量是所有对象共享的数据。
b:成员变量是每个对象所特有的数据。- 静态的优点和弊端
优点:
对对象的共享数据进行单独空间的存储,节省内存,没有必要每个对象都存储一份可直接被类名调用。
弊端:
生命周期过长,随着类的消失而消失。
访问出现权限,即静态虽好但只能访问静态。- 什么使用使用静态呢?
(1)当所有对象共享某个数据的时候,就把这个成员变量定义为静态修饰的。
(2)当某个方法没有访问该类中的非静态成员,就可以把这个方法定义为静态修饰。
静态的生命周期比较长,所以一般不推荐使用。- 静态代码块
(1)它只执行一次,它比main还先执行。
(2)执行顺序
静态代码块--构造代码块--构造方法
12、制作API(次重点)
API(全拼):Application Program Interface 应用程序编程接口。
- 类中的内容需要用文档注释。
- 使用JDK\bin目录下的javadoc工具。
格式:javadoc -d 目录 -author -version ArrayTool.java
13. 单例设计模式
- 设计模式
解决某类问题行之有效的方法,是一种思想,是规律的总结。- 用来保证某个类在内存中只有一个对象
- 保证唯一性的思想及步骤
(1)为了避免其他程序建立该类对象,先禁止其他程序建立该类对象,即将构造函数私有化。
(2)为了其他程序访问到该类对象,须在本类中创建一个该类私有对象。
(3)为了方便其他程序访问到该类对象,可对外提供一个公共访问方式。
比如:API中的Runtime类就是单例设计模式。
(4)单例设计模式的两种方式
a:饿汉式 当类加载的时候,就创建对象。
class Student{
private Student(){}
private static final Student s = new Student();
public static Student getInstance(){
return s;
}
}
b:懒汉式 当使用的使用,才去创建对象。
class Student{
private Student(){}
private static final Student s = null;
public static Student getInstance(){
if(s==null){
//线程1就进来了,线程2就进来了。
s = new Student();
}
return s;
}
}
(5)饿汉式和懒汉式的区别
a:饿汉式是类一加载进内存就创建好了对象。
b:懒汉式则是类才加载进内存的时候,对象还没有存在,只有调用了getInstance()方法时,对象才开始创建。
c:懒汉式是延迟加载,如果多个线程同时操作懒汉式时就有可能出现线程安全问题。
解决线程安全问题:可以加同步来解决。但是加了同步之后,每一次都要比较锁,效率就变慢了,所以可以加双重判断来提高程序效率。
注:开发常用饿汉式,因为饿汉式简单安全。懒汉式多线程的时候容易发生问题。
14. Math类的使用(重点)
- 数学操作类:该类没有构造函数,方法均为静态的。
- 掌握内容
(1)成员变量
E:比任何其他值都更接近e(即自然对数的底数)的double值。
PI:比任何其他值都更接近pi(即圆的周长与直径之比)的double值。
(2)成员方法
static double abs(double a):返回 double 值的绝对值。返回绝对值。
static double ceil(double a):返回最小的(最接近负无穷大)double 值,该值大于等于参数,并等于某个整数。
static double floor(double a):返回最大的(最接近正无穷大)double 值,该值小于等于参数,并等于某个整数。
max:返回两个值中较大的那个。
min:返回两个值中较小的那个。
static long round(double a):返回最接近参数的 long。
static int round(float a):返回最接近参数的 int。
static double random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
static double pow(double a, double b):返回第一个参数的第二个参数次幂的值。
static double sqrt(double a):返回正确舍入的 double 值的正平方根。
Random类的使用(重点)
- 产生随机数的类
- 掌握内容
(1)构造方法
Random():创建一个新的随机数生成器。
Random(long seed):使用单个 long 种子创建一个新的随机数生成器。
(2)成员方法
int nextInt():返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。
int nextInt(int n):返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。
16. Scanner类的使用
- 可以获取从键盘的输入数据
- 掌握内容
(1)构造方法
Scanner(InputStream source) 构造一个新的Scanner,生成的值是从指定的输入流扫描的。
如:Scanner sc = new Scanner(System.in);
(2)方法摘要
sc.nextInt():获取整型数据。
sc.nextLine():获取字符串数据。
17、继承(重点)
- 什么是继承
把很多类的相同特征和行为进行抽取,用一个类来描述。让多个类和这个类产生一个关系。
这样的话,多个类就可以省略很多代码。这个关系就是继承。java中用extends关键字表示。- 继承的体系结构
(1)多个具体的对象,不断的向上抽取共享的内容,最终形成了一个体系。这个体系叫做继承体系。
(2)继承体系的学习和使用原则
a:学习顶层的内容。因为他是整个体系的共性内容。
b:创建子类使用。也就是使用底层的具体对象。
- 继承的特点
(1)java中只能单继承,没有多继承。
(2)java可以有多重(层)继承。- 继承的好处
(1)继承的出现提高了代码的复用性。
(2)继承的出现让类与类之间产生了关系,提供了多态的前提。- 子父类中的成员关系
(1)成员变量
在子类方法中使用一个变量时:
首先,在方法的局部变量中找这个变量,有则使用。
否则,在本类中找成员变量,有则使用。
否则,在父类中找成员变量,有则使用。
否则,报错。
(2)成员方法
用子类对象使用一个方法时:
首先,在子类中找这个方法,有则使用。
否则,在父类中找这个方法,有则使用。
否则,报错。- 重写和重载的区别
(1)重载:在同一类中。方法名相同,参数列表不同。重载可以改变返回类型。
(2)重写:在不同类中(子父类中)。方法声明相同(返回类型,方法名,参数列表均相同)。
重写需要注意:
(1)子类方法的访问权限要大于等于父类方法的访问权限。
(2)静态只能重写静态。但是这种情况一般不会出现。- 构造方法
(1)子类的实例化过程
子类创建对象时,会先去创建父类的对象。默认是去调用父类的无参构造方法。
(2)子类构造方法中,第一行默认是super()
为什么子类中第一行会默认有super()?
因为他继承父类的成员使用,使用前这些成员必须初始化,而他们是父类的成员,所以,必须通过父类进行初始化。
所以,会先创建一个父类的对象。
当父类没有无参构造方法时:必须使用this或者super调用其他的构造方法。- this和super的区别
(1)this:代表本类对象的引用。
(2)super:代表父类的存储空间。
18. final关键字(重点)
- 最终的意思,可以用于修饰类,方法,变量。
- final修饰的类不能被继承。
- final修饰的方法不能被重写。
- final修饰的变量是一个常量。只能被赋值一次。
- 内部类只能访问被final修饰的局部变量。
19. 抽象类(重点)
- 多个类有相同的方法声明,但是方法体不一样。这个时候,我们考虑把方法声明进行抽取。让子类继承后,自己去实现方法体。没有方法体的方法,我们需要用抽象标志下。
抽象的关键字是:abstract。- 抽象类
该方法称为抽象方法,包含抽象方法的类就是抽象类。- 抽象类的特点
(1)抽象类和抽象方法都要用abstract进行修饰。
(2)抽象类不能被实例化。
(3)抽象类中不一定有抽象方法,但是,有抽象方法的类一定是抽象类。- 抽象类中数据的特点
(1)成员变量
抽象类中可以有变量,也可以有常量。
(2)成员方法
抽象类中可以有抽象方法,也可以有非抽象方法。
(3)构造方法
抽象类是一个类,所以,它有构造方法。虽然本身不能实例化。但是可以给子类实例化使用。- 抽象类中的问题
(1)抽象类中是否有构造方法?能不能被实例化?如果不能,为什么有构造方法?
a:抽象类有构造方法。
b:抽象类不能被实例化。
c:抽象类中的构造方法供子类实例化调用。
(2)抽象关键字abstract不可以和哪些关键字共存?
a:private
私有内容子类继承不到,所以,不能重写。而abstract修饰的方法,要求被重写。两者冲突。
b:final
final修饰的方法不能被重写。而abstract修饰的方法,要求被重写。两者冲突。
c:static
假如一个抽象方法能通过static修饰,那么这个方法,就可以直接通过类名调用。而抽象方法是没有方法体的,这样的调用无意义。所以,不能用static修饰。
(3)抽象类中可不可以没有抽象方法?如果可以,这样的类有什么用吗?
a:抽象类可以没有抽象方法。
b:抽象类中没有抽象方法的作用,只是为了不让别的类建立该抽象类对象。这个在awt中有体现。
20. 接口interface
- 什么叫接口
当一个类中的方法都是抽象的时候,java提供了另一种表示方式,叫接口。
用interface关键字表示。实现接口关系用implements表示。- 接口的成员特点
(1)成员变量
是常量,默认修饰 public static final。
(2)成员方法
都是抽象的,默认修饰 public abstract。- 关系
(1)类与类的关系——继承
类与类只能单继承,可以多重继承。
(2)类和接口的关系——实现
类在继承一个类的同时,可以实现多个接口。
(3)接口和接口的关系——继承
接口可以多继承接口。- 接口的特点
(1)是对外暴露的规则。
(2)是功能的扩展。
(3)接口的出现降低代码的耦合性。
a:耦合——类与类之间的关系
b:内聚——类完成功能的能力
编程规范:低耦合,高内聚。
(4)接口可以多实现。如:CPU和主板、笔记本的USB插口、插座。- 接口和抽象类的区别
(1)抽象类只能被单继承。
(2)接口可以多实现,接口的出现避免了多继承的局限性。
(3)抽象类中的数据特点
a:成员变量:可以是变量,也可以是常量。
b:成员方法:可以是抽象方法,也可以是非抽象方法。
c:构造方法:有构造方法。
(4)接口中的数据特点
a:成员变量:是常量。默认修饰 public static final。
b:成员方法:都是抽象方法。都有默认修饰 public abstract。
c:构造方法:没有构造方法。
(5)抽象类中定义的是继承体系中的共性功能。
(6)接口中定义的是继承体系中的扩展功能。
(7)抽象类被继承是"is a"关系:xx是yy的一种
(8)接口被实现是"like a"关系:xx像yy的一种
21. 多态
- 什么是多态
同一个对象,在程序不同时刻的多种运行状态。举例:动物,狗是狗,狗是动物。水(气态,液态,固态)。- 多态前提
(1)存在着继承或者实现关系。
(2)有方法的重写。
(3)父类(接口)引用指向子类(实现)对象。- 多态的好处和弊端
好处:多态的存在提高了程序的扩展性和后期可维护性。
弊端:虽然可以预先使用,但是只能访问父类中已有的功能,运行的是后期子类的功能内容。不能预先使用子类中定义的特有功能。- 多态中对象调用成员的特点
Fu f = new Zi();
(1)成员变量
编译看左边,运行看左边。
(2)成员方法
编译看左边,运行看右边。
(3)静态方法
编译看左边,运行看左边。- 多态的思想
指挥同一批对象做事情。举例:带兵打仗,下课等。
22. instanceof关键字
- 用于判断某个对象是否是某种类型。
- 格式
对象名 instanceof 子类(实现)名
23. Object类
- 是所有类的根类,超类。
Java中提供的类以及我们自定义的类都直接或者间接的继承自Object类。- Object类中的方法
(1)void finalize():当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
(2)Class getClass():获取对象的字节码文件的描述类,后面再讲反射的时候还会在说这个类。
String name = s.getClass().getName();
(3)int hashCode():获取对象的哈希值。其实就是对象的内存地址值十六进制表示。
(4)String toString():返回对象的字符串表示。
表示格式:
getClass().getName()+"@"+Integer.toHexString(hashCode());
一般我们输出对象名的时候,其实底层调用的就是该对象的toString()方法。这种返回没有意义,所以,我们会重写这个方法,显示类的成员变量信息。
(5)boolean equals(Object obj):用于比较两个对象的地址值是否相同。
我们获取对象后,比较它的地址值意义不大。所以也会对这个方法进行重写。重写要完成什么功能,是根据需求定的。- ==和equals的用法
(1)==的用法
a:可以用于比较基本数据类型,比较的就是基本数据类型的值是否相等。
b:可以用于比较引用数据类型,比较的是对象的地址值是否相等。
(2)equals的用法
equals只能用于比较引用数据类型的。
a:Object提供的equals是用于比较对象地址值是否相同。
b:自定义类中,如果重写了equals方法,那么就是按照你自己的需求来比较的。
24. package关键字
- 包:其实就是文件夹。用于区分不同包下相同的类名。
- 好处
(1)对类文件进行分类管理。
(2)给类提供了多层命名空间
aaa.Demo
bbb.Demo
(3)写在程序文件的第一行。
(4)包也是一种封装形式。
25. import关键字
- 导入包的关键字
- 格式
import 包名;
注意:
(1)一个程序文件中只有一个package,可以有多个import。
(2)用来导包中的类,不导入包中的包。
(3)通常写import mypack.Demo,明确自己使用的类。- 关键字的顺序
类,包,导包这些关键的顺序。
包 -- > 到包 -- > 类
26. 不同修饰符可以修饰哪些内容
- 包的权限访问修饰
本类中 同一个包中 不同包中的子类中 不同包中
private √
默认 √ √
protected √ √ √
public √ √ √ √
- 类、方法、变量的访问修饰
类 构造方法 成员变量 成员方法
public √ √ √ √
默认 √ √ √ √
protected √ √ √
private √ √ √
static √ √
final √ √ √
abstract √ √
一般格式:
(1)成员变量
权限修饰符+static/final+数据类型+成员变量
如: public static final int NUM = 10;
(2)成员方法
权限修饰符+static/final/abstract+返回类型+方法名
27. 内部类(次重点)
- 定义
把一个类定义在某个类中的,这个类就被称为内部类,内置类,嵌套类。- 访问特点
(1)内部类可以直接访问外部类中的成员,因为内部类持有外部类的引用。
格式:外部类名.this
(2)外部类要想访问内部类的成员,必须创建对象访问。- 内部类的访问格式
(1)当内部类定义在外部类的成员位置,而且非私有,则可以在其他外部类中直接建立内部类对象。
格式:外部类名.内部类名 变量名 = new 外部类对象.内部类对象
如:Outer.Inner in = new Outer().new Inner()
(2)当内部类在外部类成员位置,且被static修饰时
a:外部其他类可直接访问静态内部类的非静态成员
格式:new 外部类名.内部类名().内部类成员
如:new Outer.Inner().function();
b:外部其他类可直接访问静态内部类的静态成员
格式:new 外部类名.内部类名.内部类成员
如:new Outer.Inner.function();- 什么使用时候内部类呢
假如有A类和B类,A类想直接访问B类的成员,B类访问A类成员的时候,需要创建A类对象进行访问,这个时候,就可以把A类定义为B类的内部类。- 内部类的位置
(1)成员位置
a:可以被private修饰(Body,Heart)
b:可以被static修饰。(它访问的外部类的成员必须是静态的)
(2)局部位置
a:可以直接访问外部类中的成员,因为还持有外部类的持用。
b:也可以直接访问局部成员,但是局部成员要用final修饰。
注意:局部内部类不能用private和static修饰- 通过class文件我们就可以区分是否带有内部类,以及内部类的位置
Outer1Inner:局部内部类。
28. 匿名内部类(局部内部类的简写) (重点)
- 前提:继承一个类或者实现一个接口(注意不要弄混匿名内部类的前提和多态的前提)
- 格式
new 父类名或者接口名(){
重写父类方法或者实现接口中的方法。
也可以自定义其他方法。
};- 什么时候定义匿名内部类
匿名内部类只是为了简化书写,匿名内部类有局限,通常定义匿名内部类时,该类方法不超过3个。- 匿名内部类的好处和弊端
好处:简化代码书写。
弊端:
(1)不能直接调用自己的特有方法。
(2)不能执行强转换动作。
如果该类里面方法较多,不允许使用匿名内部类。
29. 模板设计模式
在定义功能时,功能的一部分是确定的,有一部分是不确定的,而且确定的部分在使用不确定的部分,可将不确定的部分暴露出去,由该类的子类去完成。
如:求一段程序的运行时间例子。
30. 异常
- 程序运行过程中的不正常现象就叫异常。
- 导致程序运行不正常的现象有很多,所以,就有很多的异常对象。而这些异常对象存在着共性的内容,所以,可以不断的进行抽取。最终形成了异常的体系结构。
异常体系的根类是:Throwable
Throwable:
|--Error:重大的问题,我们处理不了。也不需要编写代码处理。比如说内存溢出。
|--Exception:一般性的错误,是需要我们编写代码进行处理的。
|--RuntimeException:运行时异常,这个我们也不需要处理。其实就是为了让他在运行时出问题,然后我们回来修改代码。- 异常的分类(2种)
(1)编译时被检测异常
该异常在编译时,如果没有处理(没有抛也没有try),编译失败。
该异常被标识,代表这可以被处理。
(2)运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的发生,建议不处理,让程序停止。需要对代码进行修正。- 异常体系的特点
异常体系中的所有类及其子类对象都具备可抛性。也就是说可以被throw和throws关键字所操作。- main方法是如何处理异常的。
(1)在main里面编写代码进行处理
(2)交给jvm自己进行处理。采用的是jvm的默认处理方式。
其实就是相当于调用了异常对象的printStackTrace()方法。- Throwable类的学习
(1)getMessage():获取异常信息,返回字符串。
(2)toString():获取异常类名和异常信息,返回字符串。
(3)printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。- 异常的处理
(1)try...catch...finally
基本格式:
try{
可能出现异常的代码
}catch(异常对象){
异常处理代码
}finally{
释放资源
}
变形格式:
try...catch
try...catch...catch...
try...catch...catch...finally
(2)多个异常同时被捕获的时候,记住一个原则
先处理小的,再处理的。
(3)finally:永远被执行,除非退出jvm。System.exit(0)。
(4)面试题
A:final,finally,finalize区别。
答:
①final是最终的意思。它可以用于修饰类,成员变量,成员方法。它修饰的类不能被继承,它修饰的变量时常量,它修饰的方法不能被重写。
②finally:是异常处理里面的关键字。它其中的代码永远被执行。
特殊情况:在执行它之前jvm退出。System.exit(0);
③finalize:是Object类中的一个方法。它是于垃圾回收器调用的方式。
B:假如catch中有return语句,finally里中的代码会执行吗?是在return前,还是在return后呢?
答:会。在return前执行finally里面的代码。- Exception和RuntimeException的区别
(1)Exception:一般性的错误,是需要我们编写代码进行处理的。
(2)RuntimeException:运行时异常,这个我们也不需要处理。其实就是为了让他在运行时出问题,然后我们回来修改代码。
(3)在用throws抛出一个的时候,如果这个异常是属于RuntimeException的体系的时候,我们在调用的地方可以不用处理。(RuntimeException和RuntimeException的子类)
(4)在用throws抛出一个的时候,如果这个异常是属于Exception的体系的时候,我们在调用的地方必须进行处理或者继续抛出。- 自定义异常
自定义类继承Exception或者RuntimeException。
1.为了让该自定义类具备可抛性。
2.让该类具备操作异常的共性方法。
class MyExcepiton extends Exception{
MyExcepiton(){}
MyExcepiton(String message){
super(message);
}
}
class MyException extends RuntimeException{
MyExcepiton(){}
MyExcepiton(String message){
super(message);
}
}- throws和throw的区别
(1)有throws的时候可以没有throw。
(2)有throw的时候,如果throw抛的异常是Exception体系,那么必须有throws在方法上声明。
(3)throws用于方法的声明上,其后跟的是异常类名,后面可以跟多个异常类,之间用逗号隔开。
(4)throw用于方法体中,其后跟的是一个异常对象名。
31. String类:字符串(重点)
- 创建字符串对象
(1)String():无参构造。
举例:
String s = new String();
s = "hello";
sop(s);
(2)String(byte[] bys):传一个字节数组作为参数。
举例:
byte[] bys = {97,98,99,100,101};
String s = new String(bys);
sop(s);
(3)String(byte[] bys,int index,int length):把字节数组的一部分转换成一个字符串。
举例:
byte[] bys = {97,98,99,100,101};
String s = new String(bys,1,2);
sop(s);
(4)String(char[] chs):传一个字符数组作为参数。
举例:
char[] chs = {'a','b','c','d','e'};
String s = new String(chs);
sop(s);
(5)String(char[] chs,int index,int length):把字符数组的一部分转换成一个字符串。
举例:
char[] chs = {'a','b','c','d','e'};
String s = new String(chs,1,2);
sop(s);
(6)String(String str):把一个字符串传递过来作为参数。
举例:
char[] chs = {'a','b','c','d','e'};
String ss = new String(s);
sop(ss);
(7)直接把字符串常量赋值给字符串引用对象。(最常用)
举例:
String s = "hello";
sop(s);- 面试题
(1)请问String s = new String("hello");创建了几个对象。
答:两个。一个"hello"字符串对象,在方法区的常量池;一个s对象,在栈内存。
(2)请写出下面的结果
String s1 = new String("abc");
Strign s2 = new String("abc");
String s3 = "abc";
String s4 = "abc";
sop(s1==s2); //false
sop(s1==s3); //false
sop(s3==s4); //true
(3)字符串对象一旦被创建就不能被改变。
指的是字符串常量值不改变。- 字符串中各种功能的方法
(1)判断
boolean equals(Object anObject):判断两个字符串的内容是否相同,复写了Object的方法。
boolean equalsIgnoreCase(String anotherString):判断两个字符串的内容是否相同,不区分大小写。
boolean contains(String s):判断一个字符串中是否包含另一个字符串。
注意:判断字符串是否包含特殊字符.直接表示为str.contains(".")。
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。
boolean startsWith(String suffix):测试此字符串是否以指定的前缀开始。
boolean isEmpty():测试字符串是否为空。
(2)获取
int length():返回此字符串的长度。
char charAt(int index):返回指定索引处的 char值。
int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引。
int indexOf(int ch, int fromIndex):返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引。
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
int lastIndexOf(int ch):返回指定字符在此字符串中最后一次出现处的索引。
int lastIndexOf(int ch, int fromIndex):返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引。
int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
String substring(int beginIndex) (注意:该方法substring的String是小写!):返回一个新的字符串,它是此字符串的一个子字符串。
String substring(int beginIndex, int endIndex) (注意该方法的String是小写!):返回一个新字符串,它是此字符串的一个子字符串,包含头不包含尾。
(3)转换
byte[] getBytes():(很常用!)从字符串到字节数组的方法。
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):将字符从此字符串复制到目标字符数组。
char[] toCharArray():(很常用!)从字符串到字符数组的方法。
static String copyValueOf(char[] data):返回指定数组中表示该字符序列的 String。
static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的 String。
static String valueOf(数据类型):把该数据类型的数据转换成字符串。
String toLowerCase():把字符串转换成小写。
String toUpperCase():把字符串转换成大写。
String concat(String str):将指定字符串连接到此字符串的结尾。
(4)替换
String replace(char oldChar, char newChar):用新字符替换旧字符(替换所有)。
String replace(String target, String replacement):用新的子串换旧串。
(5)分割
String[] split(String regex):根据指定的字符串把一个字符串分割成一个字符串数组。
(6)去空格
String trim():去除字符串的前后空格。
(7)比较
int compareTo(String anotherString):按字典顺序比较两个字符串。
int compareToIgnoreCase(String str):按字典顺序比较两个字符串,不考虑大小写。
32. StringBuffer
- 字符串的缓冲区,是一个容器。
- 它和String的区别
它是缓冲区可变长度的。- 构造方法
StringBuffer():构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符。
StringBuffer(int num):构造一个不带字符,但具有指定初始容量的字符串缓冲区。
StringBuffer(String str):构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。- 常用方法
(1)增加数据
append():添加各种类型的数据。
insert():在容器指定位置插入各种类型的数据。
(2)删除数据
deleteCharAt():删除指定位置的字符。
delete():还可以用于清空StringBuffer的缓冲区。
(3)替换
replace()
(4)获取
charAt()
(5)长度和容量
length():元素的个数。
capacity():元素的理论值。
(6)获取元素的位置
indexOf()
lastIndexOf()
(7)截取
substring(int start)
substring(int start,int end)
(8)反转
reverse- 字符串和StringBuffer的转换
(1)String-->StringBuffer通过构造
如:StringBuffer sb = new StringBuffer(String str)
(2)StringBuffer--String通过toString()方法
如:StringBuffer sb = new StringBuffer();
sb.toString();
33. StringBuilder
和StringBuffer的功能是一样的,但是有区别:
- StringBuffer(JDK1.0)是线程安全的。
- StringBuilder(JDK1.5)不保证线程安全。
一般来说,我们写的程序都是单线程的,所以,用StringBuilder,效率高。
4. 基本数据类型的对象包装类
- 用途
将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能操作该数据。
常用的操作之一:用于基本数据类型与字符串之间的转换。- 基本数据类型和对象类型的对应
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character- 构造方法
static int MAX_VALUE 值为 2^31-1 的常量,它表示int类型能够表示的最大值。
static int MIN_VALUE 值为 -2^31 的常量,它表示int类型能够表示的最小值。
static Class<Integer> TYPE 表示基本类型int的Class 实例。
Integer(int value) 构造一个新分配的Integer对象,它表示指定的int值。
Inreger(String s)
注意:s必须是纯数字的字符串。否则会有异常NumberFormatException。- 几个常用的方法
Integer.toBinaryString():以二进制无符号整数形式返回一个整数参数的字符串。
Integer.toOctalString():以八进制无符号整数形式返回一个整数参数的字符串。
Integer.toHexString():以十六进制无符号整数形式返回一个整数参数的字符串。
static int Integer.parseInt(String s):将字符串参数作为有符号的十进制整数进行解析,字符串必须是int型范围内的数字字符串。
static int Integer.parseInt(String s,int basic):使用第二个参数指定的基数,将字符串参数解析为有符号的整数。字符串必须是int型范围内的数字字符串。
short shortValue():以short类型返回该Integer的值。
int intValue():以int类型返回该Integer的值。
static Integer valueOf(int num):返回一个表示指定的 int 值的 Integer 实例。
static Integer valueOf(String s):返回保存指定的String的值的Integer对象。
static Integer valueOf(String s, int radix):返回一个Integer对象,该对象中保存了用第二个参数提供的基数进行。解析时从指定的String中提取的值。- 类型转换
(1)int --> Integer
int num = 20;
a:Integer i = new Integer(num);
b:Integer i = Integer.valueOf(num);
(2)Integer --> int
Integer i = new Integer(20);
a:int num = i.intValue();
(3)int --> String
int num = 20;
a:String s = String.valueOf(num);
b:String s = ""+num;
c:String s = Integer.toString(num);
(4)String --> int
String s = "20";
a:int num = Integer.parseInt(s);
b:Integer i = new Integer(s);
或者:Integer i = Integer.valueOf(s);
int num = i.intValue();