java知识汇总
文章目录
Java基础知识
基本类型
类别及其对应包装类
1. byte—Byte
2. char—Character
3. short—Short
4. int—Integer
5. long—Long
6. float—Float
7. double—Double
8. boolean—Boolean
装箱及拆箱
缘由
变化
JDK1.5以前
public class WrapperClass {
public static void main(String[] args) {
//构造器方法定义Integer包装类a,并赋值
Integer a=new Integer("5");
System.out.println(a);
//构造器方法定义Double包装类b,并赋值
Double b=new Double("5.5");
System.out.println(b);
//通过包装类.xxxValue()方法,从包装类对象中获取基本类变量
int c=a.intValue();
System.out.println(c);
double d=b.doubleValue();
System.out.println(d);
}
}
JDK1.5以后
数组的定义
一维数组
多维数组
关键字
final
static
finally
finally中的return会覆盖前面的return
面向对象
类
抽象类
含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class
类中定义抽象方法必须在具体
(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
- 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
抽象类中可以包含静态方法,接口中不能包含静态方法
抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
类变量与类函数
实例变量实例函数
继承
初始化顺序:
父类静态块与静态函数
- 子类静态块与静态函数
- 父类构造函数
- 子类构造函数
**注意**:静态块只执行一次,按顺序执行 在Java里,只有值传递,因为引用本身就是一个地址值,我们说的”传递引用“本质上也是“值传递”,只不过传递的是地址值。 在方法中,改变一个对象参数的引用不会影响到原始引用。这是很自然的。 举个例子,假设在函数外有 A a = new A();那么引用a指向堆中的一个对象A()。
多态
向上转型
把子类对象当做父类对象来用
class Father{}
class Son extends(Father){}
Father f1 = new Son();// f1的内存空间实际上仍然是Son的内存空间,但引用是Father,相当于把Son当Father用
向下转型
是向上转型的还原
Son s1 = (Son) f1; //此处将f1重新交给son对象引用,原因是因为f1的内存结构就是son的内存结构
权限关系
public | protected | default | private | |
---|---|---|---|---|
同一类 | √ | √ | √ | √ |
同包 | √ | √ | √ | |
不同包子类 | √ | √ | ||
不同包非子类 | √ |
一些工具类
String,StringBuilder,StringBuffer
- String 不可变,String直接赋值时从常量池中寻找,用new时产生两个对象,一个对象指向常量池,另一个对象指向此对象
集合类
语法
关于循环的优化
- 强度削弱
- 删除归纳变量
- 代码外提
判断
switch(x)// required: 'char, byte, short, int, Character, Byte, Short, Integer, String, or an enum'
{
default:
System.out.println("Hello");
}
Java高级知识
流与文件
流
输入流:
从其中读入一个字节序列的对象
输出流:
向其中写入一个字节序列的对象
目标:
1. 文件
2. 网络连接
3. 内存块
分类:
1. 字符流
2. 字节流
基础:
抽象类InputStream和OutputStream
可以用.表示当前目录,..表示上级目录。
读写字节
abstract int read()
:
读入一个字节,并返回读入的字节,或者在遇到输入源结尾时返回-1,在设计具体的的输入流类时,必须覆盖这个方法
abstract void write(int b)
:
完整的流家族
组合流过滤器
文件
创建文件
java.io.File.createNewFile()
java.io.FileOutPutStream
,会自动创造文件,如果不存在该文件
File
Instances of this class may or may not denote an actual file-system
object such as a file or a directory.
属于对于一个文件的映射(可以实际上并不存在这个文件,通过createNewFile()创建)
有各种方法模拟人在操作系统上对文件的操作
异常
要求
1. 返回到一种安全状态,并能够让用户执行一些其他的命令;
2. 允许用户保存所有操作的结果,并以妥善的方式终止程序。
类型
1. 用户输入错误
2. 设备错误
3. 物理限制
4. 代码错误
异常分类
**异常对象都是派生于Throwable类的一个实例**
**如果Java中内置的异常类不能够满足需求,用户可以创建自己的异常类**
由程序错误导致的异常属于RuntimeException;
- ·错误的类型转换。
- ·数组访问越界。
- ·访问null指针
而程序本身没有问题,但由于像I/O错误这类问题导致的异常属于其他异常。
·试图在文件尾部后面读取数据。
·试图打开一个不存在的文件。
·试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在
- 派生于Error类或RuntimeException类的所有异常称为非受查(unchecked)异常,
- 所有其他的异常称为受查(checked)异常。
所有错误都发生在运行时。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jSFa7vIC-1604418877245)(E:\Typora\java.assets\image-20200723093738771.png)]
异常声明与抛出
声明
1. 调用一个抛出受查异常的方法,例如,FileInputStream构造器。
2. 程序运行过程中发现错误,并且利用throw语句抛出一个受查异常。//必须声明
3)程序出现错误,例如,a[–1]=0会抛出一个ArrayIndexOutOfBoundsException这样的非受查异常。
4)Java虚拟机和运行时库出现的内部错误。
警告:如果在子类中覆盖了超类的一个方法,子类方法中声明的受查异常不能比超类方法中声明的异常更通用(也就是说,子类方法中可以抛出更特定的异常,或者根本不抛出任何异常)
抛出
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kmUgxe8p-1604418877248)(E:\Typora\java.assets\image-20200723095652535.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dz3SPKyx-1604418877251)(C:\Users\lifan\AppData\Roaming\Typora\typora-user-images\image-20200723095711297.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V6Kf40OM-1604418877254)(E:\Typora\java.assets\image-20200723095854939.png)]
步骤
1)找到一个合适的异常类。
2)创建这个类的一个对象。
3)将对象抛出。
自定义异常:定义一个派生于Exception的类,或者派生于Exception子类的类
异常捕获
注意
1. 要想捕获一个异常,必须设置try/catch语句块
2. 如果在try语句块中的任何代码抛出了一个在catch子句中说明的异常类,
1. 程序将跳过try语句块的其余代码。
2. 程序将执行catch子句中的处理器代码。
3. 如果在try语句块中的代码没有抛出任何异常,那么程序将跳过catch子句。
4. 如果方法中的任何代码抛出了一个在catch子句中没有声明的异常类型,那么这个方法就会立刻退出(希望调用者为这种类型的异常设计了catch子句)。
5. 同一个catch子句中可以捕获多个异常类型,只有当捕获的异常类型彼此之间不存在子类关系时才需要这个特性
6. 捕获多个异常时,异常变量隐含为final变量
7. 代码抛出了一个异常,但这个异常不是由catch子句捕获的。在这种情况下,程序将执行try语句块中的所有语句,直到有异常被抛出为止
实例
捕获多个异常
获取更多信息:
e.getMessage()
e.getClass().getName()
finally子句
注意
1. 不管是否被捕获都会被执行
2. try语句可以只有finally子句,而没有catch子句
3. 在方法返回前,finally子句的内容将被执行。如果finally子句中也有一个return语句,这个返回值将会覆盖原始的返回值
带资源的try语句
实例
try块退出时,会自动调用res.close()
可以指定多个资源
分析堆栈轨迹元素
定义
堆栈轨迹(stack trace)是一个方法调用过程的列表,它包含了程序执行过程中方法调用的特定位置
实例
可以调用Throwable类的printStackTrace方法访问堆栈轨迹的文本描述信息。
一种更灵活的方法是使用getStackTrace方法,它会得到StackTraceElement对象的一个数组,可以在你的程序中分析这个对象数组
[
静态的Thread.getAllStackTrace方法,它可以产生所有线程的堆栈轨迹
不一定要通过捕获异常来生成堆栈轨迹
Thread.dumpStack()
断言
格式
assert 条件;
assert 条件:表达式;
/**
*这两种形式都会对条件进行检测,如果结果为false,则抛出一个*AssertionError异常。在第二种形式中,表达式将被传入*AssertionError的构造器,并转换成一个消息字符串。
*/
意义
断言机制允许在测试期间向代码中插入一些检查语句。当代码发布时,这些插入的检测语句将会被自动地移走
日志
·可以很容易地取消全部日志记录,或者仅仅取消某个级别的日志,而且打开和关闭这个操作也很容易。
·可以很简单地禁止日志记录的输出,因此,将这些日志代码留在程序中的开销很小。
·日志记录可以被定向到不同的处理器,用于在控制台中显示,用于存储在文件中等。
·日志记录器和处理器都可以对记录进行过滤。过滤器可以根据过滤实现器制定的标准丢弃那些无用的记录项。
·日志记录可以采用不同的方式格式化,例如,纯文本或XML。·应用程序可以使用多个日志记录器,它们使用类似包名的这种具有层次结构的名字,例如,com.mycompany.myapp。
·在默认情况下,日志系统的配置由配置文件控制。如果需要的话,应用程序可以替换这个配置。
基本日志
- 使用全局日志记录器:global logger
Logger.getGlobal().info("File->Open menu item selected")
;
- 如果在适当的地方(如main开始)调用
Logger.getGlobal().setLevel(Level.OFF);
会取消所有的日志
高级日志
- 可以调用getLogger方法创建或获取记录器:
private static final Logger myLogger=Logger.getLogger("com.mycompany.myapp")
- 与包名相比,日志记录器的层次性更强日志记录器的父与子之间将共享某些属性。例如,如果对com.mycompany日志记录器设置了日志级别,它的子记录器也会继承这个级别。
使用方法
跟踪执行流的方法,这些调用将生成FINER级别和以字符串ENTRY和RETURN开始的日志记录
一般用途 记录那些不可预料的异常调用throwing可以记录一条FINER级别的记录和一条以THROW开始的信息
本地化
实例
下列代码确保将所有的消息记录到应用程序特定的文件中
反射
接口
- 接口绝不能含有实例域
- 子类权限不能更严格,所以实现时一定要写public
步骤
1. 将类声明为实现给定的接口。
2. 对接口中的所有方法进行定义。
特性
- 能声明接口的变量
- 接口变量必须引用实现了接口的类对象
- 可用
对象 instanceof 接口
来检查一个对象是否实现了某些接口 - 接口中的所有方法自动地属于public abstract。因此,在接口中声明方法时,不必提供关键字public。后新增静态方法和默认方法
- 接口中所有的变量都是public static final
- 接口也可以扩展
public interface 接口1 extends 接口2
解决冲突
1. **超类优先**。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
2. **接口冲突**。如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法,必须覆盖这个方法来解决冲突
Java集合
- 如果需要一个循环数组队列,就可以使用ArrayDeque类。如果需要一个链表队列,就直接使用 LinkedList类,这个类实现了Queue接口
- 集合类的基本接口是Collection接口
集合框架
collection接口
public interface Collection<E>{
boolean add(E element);// 用于添加元素
Iterator<E> iterator();// 用于遍历
int size();
boolean isEmpty();
boolean contains(Object obj);//如果集合中包含了一个与obj相等的对象,返回true
boolean containsAll(Collection<?>other);//如果这个集合包含other集合中的所有元素,返回true。
boolean addAll(Collection<?extends E>other);
boolean remove(Object obj);
void clear()
}
一些其他方法
迭代器
public interface Iterator<E>{
E next();
boolean hasNext();
void remove();
default void forEachRemaining(Consumer<?suoer E>action);
}
public interface Iterable<E>{
Iterator<E> iterator;
}
- “for each”循环可以与任何实现了Iterable接口的对象一起工作Collection接口扩展了Iterable接口。因此,对于标准类库中的任何集合都可以使用“for each”循环。
- Iterator接口的remove方法将会删除上次调用next方法时返回的元素想要用迭代器删除集合中的元素
interator.next()
然后再interator.remove()
而且不能连续remove.
集合框架中的接口
具体的集合
链表
散列集
树集
TreeSet类与散列集十分类似,不过,它比散列集有所改进。树集是一个有序集合(sorted collection)。可以以任意顺序将元素插入到集合中。在对集合进行遍历时,每个值将自动地按照排序后的顺序呈现。
队列
双端队列
优先级队列
- 优先级队列(priority queue)中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索
- 优先级队列使用了一个优雅且高效的数据结构,称为堆(heap)。堆是一个可以自我调整的二叉树,对树执行添加(add)和删除(remore)操作,可以让最小的元素移动到根,而不必花费时间对元素进行排
映射
基本操作
- 散列映射对键进行散列,树映射用键的整体顺序对元素进行排序,并将其组织成搜索树。散列或比较函数只能作用于键。与键关联的值不能进行散列或比较。
- 每当往映射中添加对象时,必须同时提供一个键。在这里,键是一个字符串,对应的值是Employee对象。要想检索一个对象,必须使用(因而,必须记住)一个键。
- 键必须是唯一的。不能对同一个键存放两个值。如果对同一个键两次调用put方法,第二个值就会取代第一个值。实际上,put将返回用这个键参数存储的上一个值
更新
就是第一次看到word时。在这种情况下,get会返回null,因此会出现一个NullPointerException异常。
以使用getOrDefault方法:
首先调用putIfAbsent方法。只有当键原先存在时才会放入一个值。
merge方法可以简化这个常见的操作。如果键原先不存在,下面的调用:
链接散列集与映射
枚举集与映射
在EnumSet的API文档中,将会看到E extends Enum这样奇怪的类型参数。简单地说,它的意思是“E是一个枚举类型。”所有的枚举类型都扩展于泛型Enum类。例如,Weekday扩展Enum
标识散列映射
视图与包装器
视图定义
- 返回一个实现Set接口的类对象,这个类的方法对原映射进行操作。这种集合称为视图。
轻量级集合包装器
子范围
不可修改的视图
算法
遗留的集合
并发
中断线程
1. 当对一个线程调用interrupt方法时,线程的中断状态将被置位。这是每一个线程都具有的boolean标志。每个线程都应该不时地检查这个标志,以判断线程是否被中断。
2. 要想弄清中断状态是否被置位,首先调用静态的Thread.currentThread方法获得当前线程,然后调用isInterrupted方法:
- 有两个非常类似的方法,interrupted和isInterrupted。Interrupted方法是一个静态方法,它检测当前的线程是否被中断。而且,调用interrupted方法会清除该线程的中断状态。另一方面,isInterrupted方法是一个实例方法,可用来检验是否有线程被中断。调用这个方法不会改变中断状态
线程状态
要确定当前状态,可调用getState方法
New(新创建)
当用new操作符创建一个新线程时,如new Thread(r)
,该线程还没有开始运行。这意味着它的状态是new。
Runnable(可运行)
一旦调用start方法,线程处于runnable状态。一个可运行的线程可能正在运行也可能没有运行
Blocked(被阻塞)与Waiting(等待)
- 当线程处于被阻塞或等待状态时,它暂时不活动。它不运行任何代码且消耗最少的资源。直到线程调度器重新激活它
- 当一个线程试图获取一个内部的对象锁(而不是java.util.concurrent库中的锁),而该锁被其他线程持有,则该线程进入阻塞状态
- 当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态
被阻塞状态与等待状态是有很大不同的
Timed waiting(计时等待)
有几个方法有一个超时参数。调用它们导致线程进入计时等待(timed waiting)状态。这一状态将一直保持到超时期满或者接收到适当的通知。
Terminated(被终止)
因为run方法正常退出而自然死亡。
因为一个没有捕获的异常终止了run方法而意外死亡。
线程属性
线程优先级
每当线程调度器有机会选择新线程时,它首先选择具有较高优先级的线程
·static void yield()
导致当前执行线程处于让步状态。如果有其他的可运行线程具有至少与此线程同样高的优先级,那么这些线程接下来会被调度。注意,这是一个静态方法。
守护线程
可以通过调用void setDaemon(boolean isDaemon)true
来将线程转换为守护线程,这一方法必须在线程启动之前调用
同步
“如果向一个变量写入值,而这个变量接下来可能会被另一个线程读取,或者,从一个变量读值,而这个变量可能是之前被另一个线程写入的,此时必须使用同步”
锁对象
基本结构
- 这一结构确保任何时刻只有一个线程进入临界区。一旦一个线程封锁了锁对象,其他任何线程都无法通过lock语句。当其他线程调用lock时,它们被阻塞,直到第一个线程释放锁对象。
- 警告:把解锁操作括在finally子句之内是至关重要的。如果在临界区的代码抛出异常,锁必须被释放。否则,其他线程将永远阻塞
其他
锁是可重入的,因为线程可以重复地获得已经持有的锁。锁保持一个持有计数(hold count)来跟踪对lock方法的嵌套调用。线程在每一次调用lock都要调用unlock来释放锁。由于这一特性,被一个锁保护的代码可以调用另一个使用相同的锁的方法。
条件对象
定义
通常,线程进入临界区,却发现在某一条件满足之后它才能执行。要使用一个条件对象(条件变量)来管理那些已经获得了一个锁但是却不能做有用工作的线程
其他
- 注意注意死锁
synchronized关键字
·锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码。
·锁可以管理试图进入被保护代码段的线程。
·锁可以拥有一个或多个相关的条件对象。
·每个条件对象管理那些已经进入被保护的代码段但还不能运行的线程。
每一个对象有一个内部锁,并且该锁有一个内部条件。由锁来管理那些试图进入synchronized方法的线程,由条件来管理那些调用wait的线程。
- wait、notifyAll以及notify方法是Object类的final方法。Condition方法必须被命名为await、signalAll和signal以便它们不会与那些方法发生冲突
局限
1. 不能中断一个正在试图获得锁的线程。
2. 试图获得锁时不能设定超时。
3. 每个锁仅有单一的条件,可能是不够的
同步阻塞
每一个Java对象有一个锁。线程可以通过调用同步方法获得锁。还有另一种机制可以获得锁,通过进入一个同步阻塞
格式
监视器
特性
1. 监视器是只包含私有域的类。
2. 每个监视器类的对象有一个相关的锁。
3. 使用该锁对所有的方法进行加锁
4. 该锁可以有任意多个相关条件
Volatile域
volatile关键字为实例域的同步访问提供了一种免锁机制。如果声明一个域为volatile,那么编译器和虚拟机就知道该域是可能被另一个线程并发更新的。
Volatile变量不能提供原子性
死锁
定义
所有线程都被阻塞。这样的状态称为死锁(deadlock)。
读写锁
步骤
阻塞队列
线程安全的集合
1. 饿汉式(线程安全,调用效率高,但是不能延时加载);
2. 懒汉式(线程安全,调用效率不高,但是能延时加载);
3. Double CheckLock实现单例:DCL也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,不建议使用);
4. 静态内部类实现模式(线程安全,调用效率高,可以延时加载);
5. 枚举类(线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用)。
网络编程
端口
端口分类
通信协议:
- 公有端口:0-1023
- HTTP:80
- HTTPS:443
- FTP: 21
netstat -ano #查看所有端口
netstat -ano|findstr "5900" #查看指定端口
tasklist|findstr"8696" #查看指定端口的进程
Tcp/Ip协议簇
实际上是一组协议
重要:
TCP:
连接,稳定
三次握手,四次挥手
客户端,服务端
传输完成,释放连接,效率低
UDP
出名的协议:
- TCP
- IP
用TCP协议通信
- 服务器端运用
serversocket
监听指定端口,serversocket.accept
接受客户端的socket
,然后再通过流传输信息
用UDP协议通信
lambda语法
作用:简化代码,
**方法引用:**双冒号语法
JavaBean
只是一种类的规范
Swing
JFrame 类的常用构造方法如下所示。
- JFrame():构造一个初始时不可见的新窗体。
- JFrame==(String title)==:创建一个具有 title 指定标题的不可见新窗体。
辅助工具使用
Hutool
概览
引入
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.3</version>
</dependency>
easyExcel
引入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
一些疑惑
InputStream是抽象类,但为什么会有其的实例例如
InputStream in= socket.getInputStream();
这里的变量"in"只保存对一个对象的引用,该对象可以满足"is a inputstream"的要求。这意味着变量"in"可以容纳扩展输入流的具体类的任何瞬间,例如audioinputstream,它满足条件"is a inputstream"。我认为这与多态性有关。
抽象类不能被实例化,但可以被子类化,当然,也可以通过匿名内部类来达到这种目的
最新文章
- manachor
- SQL CURSOR
- STM32之USART-RS485
- 深入JVM-垃圾收集器常用的GC参数
- [python]pip常用命令(转载)
- 解决eclipse复制粘贴js代码卡死的问题
- 第2组UI组件:TextView及其子类
- CentOS 6.4安装搭建Tomcat 7
- 用Wget进行下载
- Android(java)学习笔记238:多媒体之图片画画板案例
- 使用sae定时执行Python脚本
- Android bitmap序列化
- Cluster Table
- iOS 添加导航按钮
- Uva 3708 Graveyard
- sql连接语句
- C#总结(六)EventBus事件总线的使用-自己实现事件总线
- javaweb 发布目录
- JavaScript递归中的作用域问题
- Event Recommendation Engine Challenge分步解析第五步