java的类
java的类
2020/9/3 11:39:48
Object类
常用的包
java.lang包 - 该包是Java语言的核心包,该包中的内容由Java虚拟机自动导入。
- 如:String类、System类等
java.util包 - 该包是Java语言的工具包,该包中提供大量工具类和集合类。
- 如:Scanner类、Random类等
java.io包 - 该包是Java语言的输入输出包,该包中提供读取文件的类。
- 如:FileInputStream类、FileOutputStream类等
java.net包 - 该包是Java语言的网络包,该包中提供大量网络编程类。
- 如:ServerSocket类、Socket类等
... ...
Object类
(1)基本概念
java.lang.Object类是类层次结构的根类,任何类都是该类的直接或间接子类。
(2)常用的方法
Object() - 使用无参的方式构造对象。
boolean equals(Object obj) - 用于判断调用对象是否与参数对象相等。
- 该方法默认比较两个对象的地址,与 == 运算符的结果一致。
- 若希望该方法比较两个对象的内容,则需要重写该方法。
int hashCode() - 用于获取调用对象的哈希码值(内存地址的编号)。
- 若两个对象调用equals方法的结果相等,则各自调用hashCode方法的结果相同
- 若两个对象调用equals方法的结果不相等,则各自调用该方法的结果不相同。
- 因此上述两个方法中只要有一个重写,则另外一个也要重写。
- 为了使得该方法的结果与equals方法保持一致,因此重写该方法。
String toString() - 用于获取调用对象的字符串形式。
- 该方法默认返回的字符串为:包名.类名@哈希码的十六进制形式。
- 为了使得该方法返回更有意义的字符串内容,需要重写该方法。
- 使用print()/println()打印引用或字符串连接引用时,会自动调用该方法
包装类和数学处理类
如:
int num = 5;
Person p = new Person();
Java语言是一门纯面向对象的编程语言。
public class MyInteger {
private int num = 5;
}
MyInteger mi = new MyInteger();
包装类的概念
在某些特殊场合(集合)中要求所有的数据内容都必须是对象,而基本数据类型声明的变量并不满足该要求,
此时就需要对变量进行对象化处理打包成对象,该机制需要使用包装类。
包装类的分类
int => java.lang.Integer类
char => java.lang.Character类
其它类型都是将首字母变大写。
Integer类
(1)基本概念
java.lang.Integer类里面提供了一个int类型的成员变量用于包装int类型。
该类由final关键字修饰表示不能被继承。
(2)常用的方法
Integer(int value) - 根据参数指定的整数来构造对象。
Integer(String s) - 根据参数指定的字符串来构造对象。
该类重写了equals()、hashCode()以及toString()方法
int intValue() - 用于获取调用对象中的int数值并返回。
static Integer valueOf(int i) - 根据参数指定的整数值得到Integer类型的对象
static int parseInt(String s) - 将字符串类型转换为int类型并返回。
BigDecimal类
(1)基本概念
由于float类型和double类型运算会有误差,若需要实现精确运算则借助java.math.BigDecimal加以描述。
(2)常用的方法
BigDecimal(String val) - 根据参数指定的字符串来构造对象。
BigDecimal add(BigDecimal augend) - 用于实现加法运算。
BigDecimal subtract(BigDecimal subtrahend) - 用于实现减法运算。
BigDecimal multiply(BigDecimal multiplicand) - 用于实现乘法运算。
BigDecimal divide(BigDecimal divisor) - 用于实现除法运算。
String类型
基本概念
java.lang.String类用于描述字符串内容,Java程序中所有的字符串字面值都可以作为此类的实例加以描述,如:"abc"等。
该类由final关键字修饰表示不能被继承。
该类描述的字符串内容是个常量不可以更改,因此可以被共享。
如:
String str1 = "abc";
str1 = "123"; - 改变str1的指向而不是指向的内容。
常量池(原理)
出于性能的考虑,Java虚拟机会将每次出现的字符串字面值放入常量池中,
若下次出现了重复的字符串时,直接使用池中已有的对象而不再需要创建新的对象。
String类
String类常用方法总结(博客园跳转)
StringBuilder类和StringBuffer类
如:
String str1 = "ab";
String str2 = "abc";
String str3 = "abcd";
(1)基本概念
由于String类型描述的字符串内容是个常量不可更改,当程序中出现大量类似的字符串时都需要单独存储,从而造成内存空间的浪费。
为了解决上述问题,可以使用StringBuilder类取代String类来描述字符串内容,该类型描述的字符串内容是可以改变的。
其中StringBuffer类是从jdk1.0开始存在,支持线程安全,因此访问效率比较低;
其中StringBuilder类是从jdk1.5开始存在,不支持线程安全,因此访问效率比较高
(2)常用的方法
StringBuilder类
常用的方法
日期相关的类
Date类
(1)基本概念
java.util.Date类主要用于描述特定的瞬间,可以精确到毫秒。
(2)常用的方法
Date() - 根据当前系统时间来构造对象。
Date(long date) - 根据参数指定的毫秒数构造对象,为距离标准时间的毫秒数。
long getTime() - 获取调用对象表示的时间距离标准时间的毫秒数。
void setTime(long time) - 用于设置调用对象表示的时间为距离标准时间
参数指定毫秒数的时间点。
SimpleDateFormat类
(1)基本概念
java.text.SimpleDateFormat类主要用于实现日期和文本之间的转换。
(2)常用的方法
SimpleDateFormat(String pattern) - 根据参数指定的字符串模式构造对象。
- y代表年 M代表月 d代表日 H代表时 m代表分 s代表秒
String format(Date date) - 用于实现日期类型向文本类型的转换。
Date parse(String source) - 用于实现文本到日期的转换。
Calendar类
(1)基本概念
java.util.Calendar类主要用于取代Date类描述特定的瞬间。
(2)常用的方法
static Calendar getInstance() - 用于获取Calendar类型的引用。
void set(int year, int month, int date, int hourOfDay, int minute, int second) - 用于设置年月日时分秒信息。
Date getTime() - 用于实现从Calendar类型向Date类型的转换。
Collection集合
常用的方法
List集合
基本概念
java.util.List集合是Collection集合的子集合,元素有先后放入次序并且可以重复
该集合的主要实现类有:ArrayList类、LinkedList类、Stack类以及Vector类。
其中ArrayList类的底层是采用数组进行数据管理的,访问方便但增删不方便。
其中LinkedList类的底层是采用链表进行数据管理的,增删方便但访问不方便。
其中Stack类的底层是采用数组进行数据管理的,该类主要用于描述具有后进先出特性的数据结构,叫做栈(last in first out 简称为:LIFO)。
其中Vector类的底层是采用数组进行数据管理的,与ArrayList类相比属于早期提供的类,支持线程安全,但效率比较低,以后的开发中首选ArrayList类。
常用的方法
泛型机制
基本概念
通常情况下集合中可以存放不同类型的对象,是因为集合将这些对象全部看做Object类型放入的,当从集合中取出元素时也是Object类型的,
为了表达该元素最真实的数据类型则需要进行强制类型转换,此时可能引发类型转换异常。
为了避免上述错误的发生,从jdk1.5开始提出泛型机制,也就是在集合名称的右侧使用<数据类型>的方式明确要求该集合中可以存放元素的类型,
若放入其他类型的元素则编译报错,
如:
List<String> lt1 = new LinkedList<String>();
泛型的本质
泛型的本质就是参数化类型,也就是让数据类型作为参数传递,其中集合中E作为形参负责占位,
当使用集合时<>中的数据类型作为实参给E进行赋值操作,从而使得集合中所有的E都被替换为实参指定的类型。
由于实参的传递支持各种各样广泛的类型,因此得名为"泛型机制".
如:
// 其中i表示形式参数,负责占位 其中E表示形式参数,负责占位
// int i = 2; E = String;
// int i = 5; E = Student;
public void show(int i) { public class List<E> {
... ...
} }
// 其中2表示实际参数,用于给形参初始化 // 其中String表示实际参数
show(2); List<String> lt1 = ...;
show(5); List<Student> lt2 = ...;
Queue集合
基本概念
java.util.Queue集合是Collection集合的子集合,与List集合属于平级关系。
该集合主要用于描述具有先进先出特征的数据结构,叫做队列(first in first out,FIFO)。
该集合的主要实现类有:LinkedList类,该类在增删方面有优势。
常用的方法
Set集合
基本概念
java.util.Set集合是Collection集合的子集合,与List集合以及Queue集合属于平级
该集合与List集合相比元素没有先后放入次序,并且不允许有重复的元素。
该集合的主要实现类有:HashSet类 和 TreeSet类。
其中HashSet类的底层是采用哈希表进行数据管理的。
其中TreeSet类的底层是采用二叉树进行数据管理的。
常用的方法
参考Collection集合中的方法即可;
Iterator<E> iterator() - 用于获取当前集合中的迭代器对象,可以取出每个元素。
其中Iterator是个接口类型,该接口的常用方法有:
boolean hasNext() - 用于判断集合中是否有可以访问的元素。
E next() - 用于获取集合中一个元素并指向下一个元素。
void remove() - 用于删除迭代器获取到的元素。
思考:
为啥要保证hashCode方法和equals方法的一致性???
解析:
只要equals方法相等则要求hashCode相同,而哈希码值相同时使用同一个哈希算法算出来的索引位置就相同,从而避免同一个元素所在索引位置不同引发的错误。
增强版的for循环(for each结构)
(1)语法格式
for(元素类型 变量名 : 数组/集合的名称) {
循环体;
}
(2)执行流程
不断地从数组/集合中取出一个元素赋值给变量后执行循环体,直到所有元素取完为止
总结:
遍历Set集合中所有元素的方式有3种:toString方法、for each结构、迭代器
遍历List集合中所有元素的方式有4种:除了上述3种外还有get方法。
Map集合
基本概念
java.util.Map<K,V>集合中存取元素的基本单位是:单对元素,具体类型参数如下:
K - 此映射所维护的键(Key)的类型
V - 映射值(Value)的类型
该集合中不能包含重复的键;每个键最多只能映射到一个值。
该集合的主要实现类有:HashMap类 和 TreeMap类。
常用的方法
异常机制
基本概念
异常就是"不正常"的含义,在Java语言中主要指程序运行阶段发生的错误。
java.lang.Throwable类是所有错误(Error)和异常(Exception)的超类。
其中Error主要用于描述比较严重无法通过编码解决的错误,如:JVM挂了。
其中Exception类主要用于描述比较轻微可以编码解决的错误,如:0作为除数。
基本分类
java.lang.Exception类是所有异常的超类,主要子类有两大类:
RuntimeException - 运行时异常,也叫作非检测性异常。
IOException和其它异常 - 其它异常,也叫作检测性异常。
- 所谓检测性异常就是指在编译阶段能够被编译器检测出来的异常。
注意:
当程序执行过程中发生异常又没有手动处理时,该异常由Java虚拟机采用默认方式处理,
而默认处理方式就是打印:异常名称、异常原因、异常发生的位置,然后终止程序
异常机制
基本概念
异常就是"不正常"的含义,在Java语言中主要指程序运行阶段发生的错误。
java.lang.Throwable类是所有错误(Error)和异常(Exception)的超类。
其中Error主要用于描述比较严重无法通过编码解决的错误,如:JVM挂了。
其中Exception类主要用于描述比较轻微可以编码解决的错误,如:0作为除数。
基本分类
java.lang.Exception类是所有异常的超类,主要子类有两大类:
RuntimeException - 运行时异常,也叫作非检测性异常。
IOException和其它异常 - 其它异常,也叫作检测性异常。
- 所谓检测性异常就是指在编译阶段能够被编译器检测出来的异常。
注意:
当程序执行过程中发生异常又没有手动处理时,该异常由Java虚拟机采用默认方式处理,而默认处理方式就是打印:异常名称、异常原因、异常发生的位置,然后终止程序
异常的避免
在以后的开发中尽量多使用if条件判断来避免异常的发生。
异常的捕获
(1)语法格式
try {
编写所有可能发生异常的语句;
}
catch(异常类型 变量名) {
编写针对该类异常处理的语句;
}
...
finally {
编写无论是否发生异常都应该执行的语句;
}
(2)注意事项
a.当需要编写多个catch分支时,切记小类型的异常处理放在大类型的上面。
懒人的写法: catch(Exception e) {}
b.finally主要用于进行善后处理,如:关闭打开的文件等。
(3)执行流程
try{
a;
b; - 可能发生异常的语句
c;
}
catch(...) {
d;
}
finally{
e;
}
若没有发生异常时的执行流程: a b c e
若发生异常时的执行流程:a b d e
异常的抛出
(1)基本概念
在某些特殊场合中发生异常无法捕获或者不便于捕获处理时,则可以将该异常转移给该方法的调用者,这个过程就叫异常的抛出。
(2)语法格式
访问权限 返回值类型 方法名称(形参列表) throws 异常类型1, 异常类型2, .. {}
如:
public void show() throws IOException {}
(3)方法重写的原则
a.要求方法名相同、参数列表相同、返回值类型相同,jdk1.5开始可以返回子类类型
b.要求访问权限不能变小,可以相同或者变大
c.要求不能抛出更大的异常
注意:
子类重写的方法不可以抛出更大的异常、平级不一样的异常,但可以抛出一样的异常、更小的异常以及不抛出异常。
自定义异常
(1)基本概念
虽然Java官方提供了大量的异常类,但没有提供针对年龄不合理等情况的异常,为了使用这种具备针对性的异常,就需要程序员自定义异常类。
(2)实现流程
a.自定义xxxException类继承Exception类或者其子类。
b.提供两个版本的构造方法,一个是无参构造方法,另一个是字符串作为参数的构造
(3)异常的产生
throw new 异常类型();
如:
throw new NullPointerException();
File类
基本概念
java.io.File类主要用于描述硬盘上文件和目录的路径信息。
使用该类可以获取文件的大小等特征信息。
常用的方法
I/O流
基本概念
I/O就是Input/Output的简写,也就是输入/输出的含义。
I/O流主要指像流水一样不间断地读写的过程。
基本分类
根据数据流动的单位不同分为:字节流 和 字符流。
其中字节流主要指以单个字节为单位进行读写的流,可以读写任意类型的文件。
其中字符流主要指以单个字符(2个字节)为单位进行读写的流,只能读写文本文件。
根据数据流动的方向不同分为:输入流 和 输出流(站在程序的角度)。
其中输入流主要指将文件中的数据内容输入到程序中,也就是读文件。
其中输出流主要指将程序中的数据内容输出到文件中,也就是写文件。
FileOutputStream类
(1)基本概念
java.io.FileOutputStream类主要用于将图像数据之类的原始字节流写入输出流中。
(2)常用的方法
FileInputStream类
(1)基本概念
java.io.FileInputStream类主要用于从输入流中读取图像数据之类的原始字节流。
(2)常用的方法
PrintStream类
(1)基本概念
java.io.PrintStream类主要用于方便地打印各种数据并具有自动刷新的功能。
(2)常用的方法
BufferedReader类
(1)基本概念
java.io.BufferedReader类主要用于从字符输入流读取单个字符、字符数组及字符串
(2)常用的方法
ObjectOutputStream类
(1)基本概念
java.io.ObjectOutputStream类主要用于将Java语言的对象整体写入输出流中。
只能将支持 java.io.Serializable 接口的对象写入流中。
类通过实现 java.io.Serializable 接口以启用其序列化功能。
所谓序列化是指将一个对象需要保存的所有相关信息有效组织成字节序列的转化过程
(2)常用的方法
ObjectInputStream类
(1)基本概念
java.io.ObjectInputStream类主要用于从输入流中将Java语言的对象整体读取出来。
(2)常用的方法
经验分享:
在以后的开发中若希望写入多个对象时,建议先将多个对象放入集合中,然后将集合看做一个对象整体调用一次writeObject方法写入。
此时只需要调用一次readObject方法就可以将整个集合读取出来,从而避免了根据返回值进行文件末尾的判断。
线程
基本概念
程序 - 数据结构 + 算法,主要指存放在硬盘上的可执行文件。
进程 - 主要指运行在内存中的程序。
目前主流的操作系统都支持多进程,为了让操作系统同时执行多个任务从而提高效率,但进程是重量级的,新建进程对系统资源的消耗比较大,因此进程的数量比较局限。
线程是进程内部的程序流,也就是操作系统中支持多进程,而每个进程的内部又可以支持多线程,并且线程是轻量级的,
新建线程会共享所在进程的系统资源,因此以后的开发中都采用多线程技术。
目前主流的多线程技术采用时间片轮转法实现多线程的并发执行,所谓并发就是宏观并行,微观串行的机制。
线程的创建
(1)线程创建和启动的方式
java.lang.Thread类主要用于描述线程,Java虚拟机允许应用程序并发地运行多个执行线程,具体创建和启动方式如下:
a.自定义类继承Thread类并重写run方法,创建该类的对象来调用start方法。
b.自定义类实现Runnable接口并重写run方法,创建该类的对象作为实参构造Thread
类型的对象,使用Thread类型的对象调用start方法。
(2)相关方法的解析
Thread() - 使用无参的方式构造对象。
Thread(Runnable target) - 根据参数指定的接口引用来构造对象。
void run() - 若构造线程对象时使用Runnable对象,则调用该方法时最终调用 Runnable对象指向的run方法;
- 若构造该线程对象时没有使用Runnable对象,则调用该方法时啥也不做
void start() - 用于启动线程,Java虚拟机会自动调用该线程的run方法。
(3)原理分析
a.执行main方法的线程叫做主线程,而执行run方法的线程叫做子线程。
b.程序启动时只有主线程来执行main方法中的代码,当start方法调用成功之后,线程的个数由1个瞬间变成了2个,
而新启动的线程去执行run方法的代码,而执行main的线程继续向下执行,两个线程各自独立运行互不影响,
当run方法执行完毕后子线程结束,而当main方法执行完毕后主线程结束。
c.主线程和子线程的先后执行次序没有明确的规定,取决于系统的调度算法。
注意:
线程创建和启动的方式一相对代码简单,但Java语言中支持单继承,若该类继承Thread类后无法继承其他类,
而线程创建和启动的方式二相对代码复杂,但该方式不影响该类继承其它类而且还可以多实现,因此以后的开发中推荐第二种方式。
线程的编号和名称
线程的常用方法
线程的同步机制
基本概念
当多个线程同时访问同一种共享资源时,可能会造成数据的覆盖等不一致性问题,
为了解决上述问题就需要对线程之间进行协调,而线程之间的通信和协调就叫线程同步机制
如:
银行卡机制 开户 => 存折 和 银行卡
解决方案
由程序结果可知:当两个线程同时进行取款操作后,导致最终的账户余额不合理。
引发的原因:线程一还没有执行完毕取款操作,线程二就已经开始取款。
解决方案: 让线程一执行完毕取款后线程二再进行取款
也就是将线程的并发操作改为串行操作
注意事项: 若两个线程依次启动执行取款操作,则多线程的意义便不复存在。
多线程的意义是同时执行多个任务,因此尽量减少串行的范围。
线程的同步实现(csdn跳转)
死锁的概念
线程一执行的代码:
public void run() {
synchronized(a) { // 持有同步锁a,等待同步锁b
synchronized(b) {
...
}
}
}
线程二执行的代码:
public void run() {
synchronized(b) { // 持有同步锁b,等待同步锁a
synchronized(a) {
...
}
}
}
注意:
在以后的开发中尽量不要使用同步代码块的嵌套使用。