这几天看了看Java的基础知识,在这篇文章中总结一下。
继承
- Java只能单继承,即子类只能继承一个父类。C++是多继承。
- super关键字用来访问父类成员,可以用于调用被子类重写的父类成员方法,也可以调用父类的构造方法,通过参数的数目和类型来决定调用哪一个构造方法。
- 一个实现类只能继承一个抽象类,但可实现多个接口。
多态
- 可以通过方法的覆盖(子类对于父类方法的覆盖和重写)来实现多态,其本质是,发送消息给某个对象,让该对象自行决定响应何种行为,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。
静态方法
- 类的属性和方法是静态成员,属于类,只有1份,由类的所有对象共享。
内部类
类型 | 名称 | 特点 | 定义方法 | 创建方法 |
---|---|---|---|---|
成员式 | 静态内部类(静态嵌套类) | public class Outer{ | 1、用static修饰,外部类加载时一起加载,无法访问外部的非静态成员; 2、相对外部类仅是包含关系,缩小了命名空间; 3、本质上是两个独立的类 | Outer.Inner inner = new Outer.Inner(); |
成员式 | 成员内部类 (常规内部类):类定义在类的内部 | public class Outer { | 1、没有static修饰; 2、需要等外部类创建了对象后才会被加载到JVM,属于外部类的某个实例; 3、访问外部类所有成员,就像访问自己的成员一样没有限制; 4、内部类的this指的是内部类的实例对象本身,如果要用外部类的实例对象就可以用类名.this的方式获得 | 1、在外部类的内部,可以用Inner inner = new Inner(); 2、在外部类外部,必须先创建外部类实例,然后再创建内部类实例 : Inner inner = new Outer().new Inner() 或者 Outer outer = new Outer(); |
局部式 | 普通内部类(局部内部类):类定义在方法的内部 | public class Outer{ | 1、仅在定义它的方法中有效; 2、局部内部类的地位和方法内的局部变量类似,因此不能修饰局部变量的修饰符也不能修饰局部内部类(public, private, protected, static等); 3、局部内部类不能访问定义它的方法的局部变量,除非这个方法定义为final | 局部内部类只能在声明的方法内是可见的,因此定义完局部内部类后,想用的话就直接在方法内实例化; |
局部式 | 匿名内部类 | public class Dog{ | 匿名内部类可以是某个类的继承子类,也可以是某个接口的实现类 | 没有名字 |
-
Java数据类型
- 类型
- 基础数据类型:byte, short, long, int, double, float, boolean, char
- 引用数据类型
- 装箱拆箱
- 装箱:对于基础数据类型,通过new包装类或者静态的valueOf方法转换为包装类型。
- 拆箱:通过intValue()把包装类型转换为基础类型
- 类型
字符串
- 字符串对象池:Java虚拟机在启动时会实例化9个对象池,存储8个基本类型的包装类对象和string对象。当在程序中直接用双引号引起来一个字符串时,JVM就到string的对象池中检查是否有值相同的对象,有就取现有的对象,否则就创建一个,并返回引用。
- 字符串反转:可以直接用StringBuffer的reverse()方法
StringBuffer buff = new StringBuffer(s);
buff.reverse().toString(); - 为了避免频繁创建和销毁对象而影响系统性能,通过String相加来拼接字符串的效率是很低的,因为每次相加都会产生一个新的字符串对象,因此,应该用StringBuffer和StringBuilder类,他们之间的区别在于StringBuilder是线程安全的。
StirngBuffer sb = new StringBuffer();
sb.append();
数组
- 在处理基本数据类型时,数组保存的是变量的值,初始化为0;而处理引用类型时,保存的是数据的引用,初始化为null。
- 拷贝数组的数据:用=只能复制引用,并没有拷贝数组的数据,他们指向的是同一段的内存空间。拷贝内容的话应该用System.arrayCopy()
System.arrayCopy(arr,0,arr2,0,arr.length())
Swing事件模型:在Swing事件模型中,组件可以触发事件,每种事件的类型由不同的类来表示。当事件被触发后时,它可以被一个或多个监听器所接收,并由监听器负责处理。所以,事件发生的地方和处理的地方是分开的。
Java文件操作
- Java所有数据的读/写,都是通过流进行的。因此,要完成一个复制文件的程序,就得有两个流对象:一个是输入流,一个是输出流。
- 随机存取文件RandomAccessFile类:可以用seek()方法随机到达任何需要存取数据的地方。
- 字节流:每次读取的单位为byte,因此主要用在内存缓存,文本复制等不需要关系流格式的地方。
- 字符流:由字节流包装而得;字符流对象创建时,需要提供一个输入或输出流。
- 序列化: 把Java对象内存中的数据编成一串二进制的数据,将这些数据放在可持久化的数据存储设备,当需要还原这些数据时,再通过反序列化将对象还原到内存中。所有需要序列化的类都必须实现Serializable接口。
进程和线程
- 进程:占用CPU、内存等资源的基本单位。
- 进程也可能是整个程序或部分程序的动态执行。
- 程序的一次执行。
- 每个独立的进程有一个程序运行的入口,顺序执行序列和程序的出口。
- 进程之间相互独立,通信比较困难
- 线程:进程的执行单位。
- 线程是一组指令的集合,或者是程序的特殊段。
- 可以在程序中独立执行,也可理解为代码运行的上下文。
- 线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
- 线程只涉及到CPU分配,一个进程中的线程是可以互相通信的,但不同进程之间的线程是不能互相通信的。
- 线程之间共享一块内存区域,通信方便。
- 实现Runnable接口的线程类的多个线程,可以更方便的访问同一个变量,而Tread类则需要内部类来进行替代。
- 关系:每个正在运行的程序都是一个进程,每个进程包含一个或多个线程。
- 多线程:允许在程序中并发执行的多个指令流,每个指令流都为一个线程,彼此互相独立。它与进程一样拥有独立的执行控制,由操作系统调度。
- 线程安全:多线程一旦操作同一块内存的数据,就可能造成数据的混乱,使用synchronized来保持线程的同步。
- 同步方法:synchronized一旦在成员方法上,就做同步方法。
- 同步代码块:用一个对象来给代码块加锁叫做同步代码块。
- Synchronized为某段代码加上锁以后,某个线程进入到该段代码后,首先检查该锁是否被占用,如果没有则继续执行;如果已经被占用,则需要等到锁被释放后才能继续执行。其中,线程执行完这段代码就是释放锁的标识。
- 线程池:一个或多个线程的集合。
- 组成部分:
- 完成任务的一个或多个线程
- 用于调度管理的管理线程
- 要求执行的任务队列。
- 特征:可最大程度利用线程;线程代码和业务代码分离。把所有线程都交给一个Executor管理,把对线程的各种操作集中在一起管理。这样,分离了业务代码和线程本身的管理代码,而且还让线程的执行效率高且易于管理。
- 组成部分:
- 进程:占用CPU、内存等资源的基本单位。
- 反射机制:为能够动态的加载一个类,动态的调用一个方法,动态的访问一个属性等动态要求而设计的。它的出发点就是JVM会为每个类创建一个Java.Lang.Class类的实例。通过该对象,可以获取该类的信息,然后通过reflect包下的API达到各种动态需求。
- Java类被加载到JVM的时候:
- 需要用该类创建对象;
- 访问该类的静态成员;
- 使用Class类的静态forName()方法,动态的加载一个指定类名的类。
- TCP与UDP
- TCP:一种面向连接的、可靠的、基于字节流的运输层通信协议。
- UDP:具有更小的消耗和更快的速度,适用于点对点传输的,并且安全性要求不高的网络应用程序(DNS,TFTP,DHCP,视频会议等)
- JDBC:一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问。
- 包括:
- 供程序员调用的API
- 需要数据库厂商提供的SPI,驱动程序
- 过程:
- 注册驱动程序:将驱动程序类加载到Java虚拟机中,用Class.forName()加载。
- 获取数据库连接:返回一个Connection接口。
- 创建会话:由Connection生成Statement会话,用于向数据库发送SQL命令
- 执行SQL语句:查询executeQuery,修改executeUpdate
- 处理结果集:ResultSet
- 关闭连接
- 包括:
事务:作为单个逻辑单元执行的一系列操作。要满足ACID。
- ACID
- A(原子性):事务必须是原子工作单元
- C(一致性):事务完成时,必须使所有数据都保持一致状态
- I(隔离性):由并发事务所做的修改必须与任何其他并发食物所做的修改隔离
- D(持久性):事务完成后,对于系统的影响是永久的
- 事务的结束只能有两种状态:提交和回滚。
- ACID
- 数据库访问对象层(DAO):让上层对象对待底层数据能够用一个对象的眼光看。
- 数据库连接池:
- 池中装有数据库的连接,程序员需要连接数据库时,只需从池子里面取一个即可,当调用Connection.close()方法时,这个连接被释放,返回到池子中,而没有真正与数据库断开连接。当连接不够时,会创建一个新的连接,同理,当连接太多时,会自动关闭一些不必要的连接。
- 使用数据库连接池与传统的JDBC的区别:获取连接的方式不同。
- 传统JDBC:通过驱动管理器DriverManager来获取连接。
- 连接池:用数据源DataSource来获取。
- Java Web:Servlet是Web容器的最基本组成单元。
- 原生态Java Web:Servlet + JSP + JavaBean
- 控制器:Servlet:根据请求的参数或URL的不同,转发相应的请求
- 视图:JSP:从JavaBean中读取数据进行展示
- 模型:JavaBean:数据存储
- 原生态Java Web:Servlet + JSP + JavaBean
- MVC:一种设计模式,要求应用程序的输入、处理和输出三者分离。
- 视图:用户看到与之交互的界面。
- 模型:数据和业务规则,代表一个应用程序的核心业务及数据模型。一个模型的代码只需要写一次就能够被多个视图重用。
- 控制器:接收用户输入并调用模型和视图完成用户需求。
- Hibernate:对象关系映射模型(ORM)的代表
- 接口:
- Session接口:执行被持久化对象的增删改查
- SessionFactory接口:负责Hibernate配置工作,创建SessionFactory对象
- Transaction接口:负责事务的相关操作
- Query接口:负责执行各种数据查询功能
- 状态:
- 瞬时态:new出的对象,未引用被收回
- 持久态:在DB有记录,有持久化标识
- 托管态:与持久对象的Session关闭后,转化为托管对象
- 接口: