JAVA知识概括
2022-03-24 11:20:46 1 举报
AI智能生成
JAVA基础知识概括
作者其他创作
大纲/内容
二、语言基础
前置知识
变量
数据类型
整数
byte
short
int
long
小数(浮点数)
float 单精度浮点型
double 双精度浮点型
布尔
boolean(取值范围只有ture/flase)
char字符串
美国标准信息交换码
万国码
String字符串
类型转换
自动类型转换
两种类型相互兼容,目标类型大于源类型
强制类型转换
两种类型相互兼容,目标类型小于源类型
三、选择结构与分支结构
基本if选择结构
if else选择结构
多重if选择结构
嵌套if选择结构
分支结构
局部变量
概念:声明在函数内部的变量,必须先赋值,再使用
作用范围:从定义行开始,到所在的代码块结束
注意:多个变量,在重合的作用范围内,不允许重名
四、循环结构
组成部分
初始部分:循环用以判断的变量
循环条件:决定是否继续循环的依据
循环操作:单次执行的逻辑代码或任务(一次循环要做的事情)
迭代部分:控制循环条件改变的增量
while循环
do while循环
for循环
流程控制语句
break
中止、跳出switch、以及所有的循环结构
continue
结束本次,进入下一次循环
八、面向对象三大特征
封装
概念:尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限
private的访问修饰符,修饰属性,达到本类可见的效果
get/set方法是外界访问私有属性的唯一通道,方法内部可对数据进行过滤。(可在set方法中添加过滤条件)
提供公共访问方法,以保证数据可以正常录入
继承
定义
程序中的继承,是类与类之间特征和行为的一种赠与或获得
类与类之间必须满足“is a”的关系
父类的选择:功能越精细,重合点越多的,越接近直接父类
父类的抽象:根据程序需要使用到的多个具体类,进行共性的提取,进而定义父类
在一组相同或类似的类中,抽取出共性的特征和行为,定义在父类中,实现重用
产生继承关系之后,子类可以使用父类中的属性和方法,也可定义子类独有的属性和方法
完整的子类 = 父类共性 + 子类独有
好处:既提高代码的复用性,又提高代码的可扩展性
Java为单继承,一个类只能有一个直接父类,但可以多级继承,属性和方法逐级叠加
不可继承
父类的构造方法,子类不可继承
父类中由private修饰的成员,不可继承(不可见)
父类中由default修饰的成员,子类不在同包时,不可继承(不可见)
方法的覆盖/重写(Override)
当父类提供的方法无法满足子类需求时,可以在子类中定义和父类相同的方法进行覆盖
要求
方法名、参数表、返回值,必须与父类完全相同
访问修饰符应与父类相同或比父类更宽泛
执行机制:子类覆盖父类方法后,优先执行子类覆盖后的方法版本
super关键字
第一种用法:在子类中,可以通过" super. "的形式访问父类的属性和方法,可解决一定的属性遮蔽、方法覆盖后的父类成员调用问题
第二种用法:super() 表示在子类构造方法的首行,调用父类的无参构造方法
继承关系下的对象创建
继承关系下,构建子类对象时,会先构建父类对象
由“父类共性”+ “子类独有”组合成一个完整的子类对象
继承关系下的对象创建流程
构建父类对象
初始化自身属性
执行自身构造方法中的逻辑代码
注意
如果子类构造方法中,没有显示定义super()或super(实参),则默认提供super()
同一个子类构造方法中,super()、this()不可同时存在
多态
概念:父类引用指向子类对象,从而产生多种形态
构成多态的前提,二者之间必须具有直接或间接的继承关系,父类引用可指向子类对象,进而形成多态
父类引用仅可调用父类中所声明的属性和方法,不可调用子类独有的属性和方法
装箱和拆箱
装箱:父类引用中保存真实子类对象,称为向上转型(多态核心概念)
拆箱:将父类应用中的真实子类对象,强转回子类本身类型,称为向下转型
注意:向下转型时,如果父类引用中的子类对象的类型与目标类型不匹配,则会发生类型转换异常
instanceof关键字
语法:父类引用 instanceof 类型(返回boolean类型的结果)
总结
多态的两种应用场景
使用父类作为方法形参,实现多态。调用方法时,可传递的实参类型包括:本类型对象+其所有的子类对象
使用父类作为方法返回值,实现多态。调用方法后,可得到的结果类型包括:本类型对象+其所有的子类对象
多态的作用
屏蔽子类间的差异
灵活、耦合度低
抽象
父类:不够完整、不够具体、不该独立存在,如何解决?通过abstract修饰类,意为抽象类,不能new对象
abstract的意思:抽象的,似是而非的,像,却又不是,具备某种对象的特征,但不完整
abstract修饰类,意为“不够完整、不够具体,不该独立存在”
即为抽象类,不能独立new对象
可被子类继承,对子类提供共性的属性和方法
可声明引用,更纯粹的使用多态
抽象类的构造方法的作用:构建子类对象时,先构建父类对象,由父类共性+子类独有组成完整的子类对象
总结
abstract修饰类:不能new对象,但可以声明引用
abstract修饰方法:只有方法声明,没有方法实现。(需包含在抽象类中)
抽象类中不一定由抽象方法,但由抽象方法的类一定是抽象类
子类继承抽象类之后,必须覆盖父类当中所有的抽象方法,否则子类还是抽象类
static关键字
静态与实例的区别
实例属性是每个对象各自持有的独立空间(多份),对象单方面修改,不会影响其他对象
静态属性是整个类共同持有的共享空间(一份),任何对象修改,都会影响其他对象
静态的概念
static可以修饰属性和方法,即为静态属性(类属性)、静态方法(类方法)
静态成员是全类所有对象共享的,全类只有一份,不因创建多个对象而产生多份
不必创建对象,也可通过类名,直接访问静态成员
经验:访问静态属性和方法时,可直接通过“类名.静态属性名”以及“类名.静态方法名”(推荐)
静态的特点
静态方法允许直接访问静态成员
静态方法不能直接访问非静态成员
静态方法中不允许使用this或super关键字
静态方法可以继承,不能覆盖,没有多态
类加载
JVM首次使用某个类时,将该类的.class文件加载到内存中,进行保存
加载时机
创建对象
创建子类对象
调用静态属性和方法
Class.forName(“全限定名”); //主动的加载一个类
静态代码块
类加载时,触发静态代码块的执行(仅一次)
执行地位:静态属性初始化之后
作用:可为静态属性赋值,或必要的初始行为
总结
static修饰的成员为静态成员,无需创建对象,可直接通过类名访问
静态方法不能直接访问非静态成员
静态方法中不能使用this或super
静态方法可以继承、不能重写、没有多态
静态代码块在类加载时被执行,且只执行一次
final
修饰类:此类不能被继承
修饰方法:此方法不能被覆盖
修饰变量:此变量值不可改变--常量(无初始值、只允许赋值一次)
局部常量:显示初始化
实例常量的赋值:显示初始化、动态代码块、构造方法
实例常量赋值deadline:在构造方法完成之前,为实例常量赋值即可
如果在构造方法中为实例常量赋值,必须保证所有的构造方法都可正确赋值
静态常量的赋值:显示初始化、静态代码块
静态常量赋值deadline:在类加载完成之前(通过类名调用之前),为静态常量赋值即可
不同常量类型的特点
基本数据类型常量:值不可变
引用数据类型常量:地址不可变
接口
接口的语法
相当于特殊的抽象类,定义方式、组成部分,与抽象类类似
接口中只能定义公开静态常量(变量)
接口中只能定义公开抽象方法(方法)
接口不是类
接口与抽象类的异同
相同
可以编译成字节码文件
不能创建对象。(接口不是类,不是模板的概念,也没有构造方法)
可以声明引用
具备Object定义的方法
不同
接口中的属性只能是公开静态常量(隐式使用public static final修饰)
接口中的方法只能是公开抽象方法(隐式使用public abstract修饰)
没有构造方法、没有动态代码块、没有静态代码块
接口的概念
接口是种能力和约定
接口的定义:能力
方法的定义:约定
经验:Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力
经验:接口支持多实现,可为类扩充多种能力
接口的规范
任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类
实现接口中的抽象方法时,访问修饰符必须是public
接口引用
同父类一样,接口也可声明为引用,并指向实现类对象
注意
仅可调用接口中所声明的方法,而不可调用实现类中独有的方法
可强转回实现类的本身类型,进行独有的属性和方法的调用。(强转前通过instanceof判断)
接口的多态
不再关注具体的类型,而是关注行为
常见关系
类与类:单继承,extends父类名称
类与接口:多实现,implements 接口名称1,接口名称2,接口名称3
接口与接口:多继承,extends 父接口名称1,父接口名称2
常量接口
将多个常用于表示状态和固定值的变量,以形态常量的形式定义在接口中统一管理,提高代码的可读性
接口
接口是一种标准
耦合度:模块与模块之间的关联程度,关联的越密切,耦合越高,关联的越松散,耦合越低
十、集合
Collection体系集合
Collection父接口:该体系结构的根接口,代表一组对象,称为“集合”,每个对象都是该集合的“元素”
List接口的特点:有序、有下标、元素可重复
Set接口的特点:无序、无下标、元素不可重复
List子接口
特点:有序、有下标、元素可以重复
继承可父接口提供的共性方法,同时定义了一些独有的与下标相关的操作方法
List实现类
JDK8的ArrayList,实际初始长度是0
首次添加元素时,需要实际分配数组空间,执行数组扩容操作
真正向数组中插入数据,(Lazy懒)用的时候再创建,或再加载,有效的降低无用内存的占用
ArrayList
数组结构存储,查询快,增删慢。//注册(1次)-> 查询(N次)
JDK 1.2发布,执行效率快,线程不安全
Vector
数组结构存储,查询快,增删慢
JDK 1.0发布,执行效率慢,线程安全
LinkedList
链表(链接列表)结构存储,查询慢、增删快
了解:Queue接口:队列、双端队列
了解:栈结构Last In First Out(后进先出)
了解:队列结构First In First Out(先进先出)
泛型集合【重点-解决应用问题】
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致
特点
编译时即可检查,而非运行时抛出异常
访问时,不必类型转换(拆箱)
不同泛型之间引用不能相互赋值,泛型不存在多态
泛型:高级类别的知识,熟练应用,需要时间、经验的积累(常用名称:E = Element / T = Type / K = Key / V = Value)
概念:约束-规范类型
泛型的场景
定义泛型
实例泛型
类:创建对象时,为类所定义的泛型,进行参数化赋值
接口:实现接口时,为接口所定义的泛型,进行参数化赋值
静态泛型
定义在方法的返回值类型前面:<T>、<T extends Object>、<T extends Comparable<T>>、<T extends Comparable<? super T>> 可应用在形参列表、返回值两种场景上,不单单可以规范泛型,还可以语义化返回值
定义在方法的形参列表当中:<?>、<? extends Object>、<? super Integer>,不支持使用& 只能应用在形参列表上,规范泛型
Collections工具类
概念:集合工具类,定义了除了存取以外的集合常用方法
public static <T extends Comparable<? super T>> void sort(List<T> list) //排序,要求:必须实现Comparable,必须可与自身类型比,以及父类类型比
public static void reverse(List<?> list) //反转、倒置元素
public static void shuffle(List<?> list) //随机重置顺序
经验:一级目标能看懂、能调用,二级目标能定义、能设计
Set子接口
特点:无序、无下标、元素不可重复(当插入新元素时,如果新元素与已有元素进行equals比较,结果为true时,则拒绝新元素的插入)
方法:全部继承自Collection中的方法
foreach循环
for(数据类型 变量名 : 容器名称){ //可遍历集合或数组(常用在无序集合上)
}
}
Set接口实现类
HashSet【重要】
HashSet的底层使用的HashMap类,即是将所有需要存入HashSet的值,直接保存在HashMap中
HashSet如何去掉重复?
先判断hashCode是否一致,==比较地址,equals比较内容
LinkedHashSet【了解】
底层使用LinkedHashMap(链表结构)存储,节点形式单独存储数据,并可以指向下一个节点,通过顺序访问节点,可保留元素插入顺序
TreeSet【了解】
实现了SortedSet接口,要求必须可以对元素排序
所有插入元素,必须实现Comparable接口,覆盖compareTo方法
根据compareTo方法返回0作为去重的依据,(意味重复)
Map体系集合
Map:地图、映射
概念:存储一对数据(Key-value),无序、无下标、键不可重复、值可以重复
HashMap算法:拿到任何一个对象好,通过hash(key)做运算,key>>>16(除以16),只可能得到0~15之间的一个数组,作为插入数组的下标
Hashtable:HashMap的线程安全版本
TreeMap:自动对key做排序,根据compareTo的返回值去重
Properties:Hashtable 子类,主要用于存储key和value都是字符串的情况,常在读取配置文件之后,保存文件中的键值对。反射、JDBC
Map集合的遍历
keySet(); 获得Map集合中所有的键。 返回的是Set集合
values(); 获得Map集合中所有的值。 返回的是Collection集合
entrySet(); 返回的是Map.Entry(Node) 包含了getKey()和getValue()。直接输出调用的是toString打印键值对
Iterator 迭代器
专注于迭代Collection体系集合的
十一、异常
什么是异常
程序在运行过程中出现的特殊情况
异常处理的必要性:任何程序都可能存在大量的未知问题、错误;如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失
异常的分类
Throwable:可抛出的,一切错误或异常的父类。位于java.lang包中
|-Error:JVM、硬件、执行逻辑错误,不能手动处理
|-Exception:程序在运行和配置过程中产生的问题,可处理
|-RuntimeException:运行时异常,可处理,可不处理
|-CheckedException:受查异常,必须处理
异常的产生
自动抛出异常:当程序在运行时遇到不符合规范的代码或结果时,会产生异常
手动抛出异常:throw new 异常类型(“实际参数”);
一旦产生异常结果:相当于执行return语句,导致程序因异常而终止
异常的传递
I.按照方法的调用链反向传递,如果最终都没有处理异常,最终交由我们的JVM进行默认异常处理(打印堆栈跟踪信息)
受查异常:throws 声明异常,声明位置:修饰在方法参数列表的后端
运行时异常:因其可处理,可不处理,无需声明
异常的处理
try{
//可能出现异常的代码
}catch(Exception e){
//捕获异常后,对异常处理的相关代码。处理方案:1、自定义2、printStackTrace();3、getMessage();
}finally{
//无论是否出现异常,都需要执行的代码。 常用于释放资源.
}
//可能出现异常的代码
}catch(Exception e){
//捕获异常后,对异常处理的相关代码。处理方案:1、自定义2、printStackTrace();3、getMessage();
}finally{
//无论是否出现异常,都需要执行的代码。 常用于释放资源.
}
II.常见异常处理结构
(1)try{ }catch(){}
(2)try{}catch(){}catch(){}
(3)try{}catch(){}finally{}
(4)Try{}catch(){}catch(){}finally{}
(5)try{}finally{}
注意:多重catch下,遵循从子到父的顺序,父类异常在最后捕获
(1)try{ }catch(){}
(2)try{}catch(){}catch(){}
(3)try{}catch(){}finally{}
(4)Try{}catch(){}catch(){}finally{}
(5)try{}finally{}
注意:多重catch下,遵循从子到父的顺序,父类异常在最后捕获
自定义异常
继承Exception(受查异常)或Exception的子类。常用RuntimeException.(运行时异常)
必要提供的内容
无参构造方法
String message参数的构造方法。定义异常原因信息
异常方法覆盖
方法名、参数列表、返回值类型必须和父类相同
子类的访问修饰符和父类相同或比父类更宽泛
子类中的方法,不能抛出比父类更宽泛的异常
扩充:方法执行中字节码操作指令
反编译:javap -verbose 文件名称(是.class) > 自定义文件名称.bytecode
多线程
进程
运行时的程序,称为进程
单核CPU在任一时间点上,只能运行一个进程
宏观并行、微观串行
cpu get NumberOfCores 获得核心数
线程
轻量级进程
程序中的一个顺序控制流程,也是CPU的基本调度单位
进程可以由单个或多个线程组成,彼此间完成不同的工作,交替执行,称为多线程
JVM虚拟机是一个进程,默认包含主线程(Main函数),可以通过代码创建多个独立线程,与Main线程并发执行
线程的组成
CPU时间片
运行数据
堆空间:存储线程需要使用的对象,多个线程可以共享堆中的对象
栈空间:存储线程需要使用的局部变量,每个线程都拥有独立的栈
线程的创建
继承Thread类,自定义类变成线程类
实现Runnable接口,赋予自定义类线程任务的能力
实现Runnable接口,不影响类继承,更灵活
线程创建后,需要调用start();方法,来启动线程,由JVM调用run()方法。直接调用run()方法并不是线程的启动
线程的状态(基本)
线程常见方法
休眠 sleep(long millis);
.当前线程主动休眠 millis毫秒,进入有限期等待!
放弃 yield();
当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
结合 join();
允许其他线程加入到当前线程中,当前线程进入无限期等待!
线程的状态(等待)
线程安全的问题
当多线程并发访问临界资源时,如果破坏了原子操作,可能会导致数据不一致
临界资源:共享资源(同一对象、堆空间),一次仅允许一个线程使用,才可保证其正确性
原子操作:不可分割的多步操作,被视作为一个整体,其顺序和步骤不能打乱或缺省
synchronized 同步锁
每个对象都有一个互斥锁标记,用来分配给线程
只有持有对象互斥锁标记的线程,才能进入对该对象加锁的同步操作中(同步方法、同步代码块)
只有线程退出同步操作时,才会释放相应的锁标记
同步方式
同步代码块
synchronized(临界资源对象){
//原子操作
//原子操作
同步方法
synchronized 返回值类型 方法名成(参数列表){
//原子操作
//原子操作
线程的状态(阻塞)
同步规则
只有在调用包含同步代码块的方法或者是同步方法时,才需要对象的锁标记
如果调用的是不包含同步代码块的方法或普通方法时,则不需要锁标记,直接调用即可
已知线程安全的内容:StringBuffer、Vector、Hashtable
死锁、生产者与消费者
线程通信
等待
wait();
必须在对obj(对象)加锁的同步代码块(或同步方法)中,在一个线程执行期间,调用了obj.wait(),该线程会释放所拥有的锁标记。同时,进入到obj的等待队列中。等待唤醒
通知(唤醒)
notify();、notifyAll();
必须在对obj加锁的同步代码块(或同步方法)中,从obj的Waiting(等待队列)中随机释放一个或全部线程。对自身线程无影响
I/O框架
什么是流
内存与存储设备之间传输数据的通道
流的分类
方向(重点)
输入流
输出流
单位
字节流
字符流
功能
节点流
过滤流
字节流
字节流的父类
InputStream(抽象类)
OutputStream(抽象类)
字节节点流
FileInputStream
FileOutputStream
字节过滤流
BufferedOutputStream
BufferedInputStream
提供了IO效率,减少访问磁盘的次数。数据存放在缓冲区中。flush刷新缓冲区,提交数据
对象流
ObjectOutputStream
ObjectInputStream
增强了读写8种基本数据类型和字符串功能
读写对象,实现对象的持久化存储
序列化/反序列化
必须实现Serializable接口。 标识序列化功能
必须保证所有属性均支持序列化
Transient修饰的为临时属性,不参与序列化
读取到文件末尾时:java.IO.EOFException
字符编码
GBK 简体中文、扩展
UTF-8 针对Unicode的可变长度字符编码
GB2312 简体中文
当编码和解码方式不一致时,会出现乱码
字符流
字符流的父类
Reader
Writer
字符节点流
FileWriter
FileReader
字符过滤流
BufferedWriter/PrintWrite
BufferedReader
支持写一行、读一行
字符节点流
桥转换流
InputStreamReader
OutputStreamWriter
可将字节流转换为字符流,可设置编码方式(编码与解码要一致)
使用步骤
创建节点流
创建过滤流,设置字符编码集
封装过滤流
读写数据
关闭流
File
FileFilter接口
反射
类的对象
基于某个类new出来的对象,也称为实例对象
类对象
类加载的产物
封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法)
一类.class文件就代表着一个类对象
获取类对象
通过类的对象,获取类对象
. Student s = new Student(); Class c = s.getClass();
通过类名获取类对象
. Class c = 类名.class;
通过静态方法获取类对象
. Class.forName(“包名.类名”);
常用方法
工厂设计模式
开发中有一个非常重要的原则:“开闭原则”。对拓展开放、对修改关闭
工厂模式主要负责对象创建的问题
可通过反射进行工厂模式的设计,完成动态的对象创建
通用编程
单例模式
只允许创建一个该类的对象
方式1:饿汉式(类加载时创建,天生线程安全);
方式2:懒汉式(使用时创建,线程不安全,需要加锁);
方式3:懒汉式(使用时创建,线程安全。无锁);
一、概述及环境搭建
概述
命名规范
类名
HelloWorld、TestPackage、MyPack、TestAnnotation、ToolsA、ToolsB(帕斯卡命名法)
函数名、变量名
main、run、TestMethod(驼峰命名法)
包名
com.qf.teach;com.qf.teach.bj;(全小写,不以.开头或结尾)
常量
HELLO_WORLD、GET_ELEMENT_BY_ID
package包的概念
class类的阐述
同一个原文件可以定义多个类
编译后,每个类都会生成独立的.class文件
一个类中,只能有一个主函数,每个类都可以有自己的主函数
public修饰的类称为公开类,要求类名必须与文件名称完全相同,包括大小写
一个源文件中,只能有一个公开类
执行机制
先编译,再解释
语言特点
面向对象
简单
跨平台
五、函数
概念
实现特定功能的一段代码,可反复使用
定义
public static void 函数名称(){
//函数的主体(功能代码)
}
//函数的主体(功能代码)
}
定义位置
定义在类的内部,与main函数并列。多数情况下,定义在main函数下面
调用
函数名()
执行顺序
函数调用时,优先执行函数内部代码,结束后,返回到函数调用处,继续向下执行
形式参数、实际参数
定义语法
public static void 函数名称 ( 形式参数 ) { //局部变量的声明
}
}
调用语法
函数名称( 实际参数 ); //为形式参数赋值
补充
1、== 比较的是地址,不是内容。所以当比较字符串时,==不够准确
2、比较字符串时,应使用 s1.equals(s2) ,可准确的比较字符串内容
3、当比较两个字符串不相同时,可使用 !s1.equals(s2)。 !(逻辑运算符:非)代表“不是”
返回值与返回值类型
1、定义返回值类型:基本数据类型、引用数据类型、void
2、return value; //函数可以返回一个结果,类型必须与函数定义的返回值类型一致
3一个函数只能有一个返回值,如果函数中包含分支,需要保证所有的分支都有正确的返回值
return的两种用法
1、return value; //表示结束当前函数,并伴有返回值,返回到函数调用处。(有具体的返回值类型)
2、return; //表示结束当前函数,直接会返回到函数调用处。(返回值类型是void)
总结
注意
一个类中可以定义多个函数,函数之间属于并列关系,不可嵌套
经验
一个函数只做一件事
好处
减少代码冗余
提高复用性
提高可读性
提高可维护性
方便分工合作
递归
实际再发中,递归可以解决一些具有既定规律的问题
当需要解决的问题可以拆分成若干个小问题,大问题、小问题的解决方法相同,有特定的规律,函数自己调用自己
设置有效的出口条件,避免无穷递归
六、数组
概念
一组连续的存储空间,存储多个相同数据类型的值
数组的创建
数据类型[] 数组名 = new 数据类型[长度]; // int [] a = new int[5];
组成概述
数组中的每个“格子”称为“数组的元素”
对元素的访问分为:“赋值”、“取值”
访问元素时,需要通过“下标”(从0开始,依次+1,自动生成)
访问的语法:数组名[下标]; //存:a[0] = 10; 取:a[0]
下标的范围:0 ~ 数组的长度-1 ,如果不在有效下标内,产生java.util.ArrayIndexOutOfBoundsException:错误下标
数组的“扩容”
创建数组时,必须显示指定长度,并在创建之后不可更改长度
扩容的思路
创建长度大于原数组的新数组
将原数组中的数据依次复制到新数组当中
数组的复制
子主循环将原数组中的所有元素数据逐一赋值给新数组题
System.arraycopy(原数组 , 原数组起始位置 , 新数组 , 新数组起始位置 , 长度);
数组类型的变量 = java.util.Arrays.copyOf(原数组 , 新长度); //根据长度创建新数组,并将原数组中的元素赋值到新数组中
地址的替换
基本数据类型的变量存储的是值
引用数据类型的变量存储的是地址
nums = newNums; //将新数组的地址,赋值给nums变量,进而在后续操作nums时,则操作长度更大的新数组
数组类型的参数
基本数据类型的传递,是“值”的传递,一方改变,不会影响另一方
引用数据类型的传递,是“地址”的传递,一方改变,会影响另一方
可变长参数
概念
可接收多个同类型实参,个数不限,使用方式与数组相同
语法
数据类型... 形参名 //必须定义在形参列表的最后,且只能有一个,支持0~N个参数。
int... = int[] String... = String[] char... = char[] double... = double[]
method(xxx , xxx[] , xxx... ); //可变长参数,是对数组的一种便利写法的补充(80%的场景用数组,20%的场景用可变长参数)
int... = int[] String... = String[] char... = char[] double... = double[]
method(xxx , xxx[] , xxx... ); //可变长参数,是对数组的一种便利写法的补充(80%的场景用数组,20%的场景用可变长参数)
排序
冒泡排序
相邻的两个值比较大小,互换位置
记忆:外层 length - 1 ;内层 length -1 - i
补充:嵌套循环约定俗称的变量命名,一重循环 i;二重循环j;三重循环k
选择排序
固定值与其他值比较大小,互换位置
记忆:外层 length - 1 ;同时外层i作为固定值,内层的j = i+1作为其他值的起始
二维数组
概念
一维数组中的一维数组,数组中的元素,还是数组
语法
注意
高维数组中的每一个元素,保存了低维数组的地址。访问array[0]等价于在访问0x0000A111("二维数组的内存分配图")
七、面向对象
程序的概念
程序是为了模拟现实世界、解决现实问题而使用计算机语言编写的指令集合
现实世界组成
程序员眼中,世界是由无数个对象组成的
什么是对象
一切客观存在的事物都是对象,万物皆对象
初期:看得见、摸得着、并真实存在,都是对象
对象有什么
任何对象,一定有自己的特征和行为
特征和行为
特征:称为属性,一般为名词,代表对象都有什么
行为:称为方法,一般为动词,代表对象能做什么
分析一个对象都有什么(属性)
分析一个对象能做什么(方法)
程序中的对象
程序如何模拟现实世界?
现实世界中,都是对象,程序中也应有对象
程序当中必须具有和现实中相同的对象,用以模拟
使用程序中的对象,代表现实中的对象,并执行操作,解决现实问题
现实生活中的对象从哪里来?
子主题手机 -> 工厂 -> 图纸(模板)
现实与程序
现实中的对象,来自于模板,通过模板造出来的实体,即是现实的对象
程序中的对象,来自于模板(“类”),通过类造出来的实体,即是程序中的对象
定义类、创建对象
类与对象的关系
类:定义了对象应具有的特征和行为,类是对象的模板
对象:拥有多个特征和行为的实体,对象是类的实例
PS:属性、实例变量、成员变量,三者等价
实例方法、成员方法,二者等价
reference - 引用、句柄、指针
实例方法、成员方法,二者等价
reference - 引用、句柄、指针
Eclipse导入外部项目
File -> Import -> General -> Existing Projects into Workspace -> Browse -> 项目的根文件夹 -> Finish
格式化代码:Ctrl + Shift + F
格式化代码:Ctrl + Shift + F
方法重载
在一个类中定义多个相同名称的方法
要求
方法名称相同
参数列表不同
与访问修饰符、返回值无关
好处
屏蔽用户的使用差异,方便
构造方法(Constructor)
概念
类中的特殊方法,主要用于创建对象
特点
名称与类名完全相同(包括大小写)
没有返回值类型
创建对象时(new对象时),触发构造方法的调用,不可通过句点的形式手工调用
注意
如果没有在类中显示定义过构造方法,则编译器默认提供无参构造方法
如果已经手动添加过有参构造方法,则无参构造方法不再默认提供,可结合需求自行添加。(建议,必须手动添加无参构造方法)
this关键字
定义
this代表“当前实例”,即是模板中的当前对象,模板服务与哪个对象,this就指向哪个对象
this的用法
调用本类中的实例属性、实例方法。例如:this.name、this.run()
调用本类中的其他构造方法。例如:this()、this(实参)。注意:必须在构造方法的首行
注意
默认来讲,实例属性和方法前的this.隐式存在
九、类
内部类
概念:在一个类的内部,再定义一个完整的类
特点
编译之后可生成独立的字节码文件
内部类可直接访问外部类的私有成员,而不破坏封装
可为外部类提供必要的内部功能组件
分类
成员
在类的内部定义,与实例变量、实例方法同级别的类
属于外部类的一个实例部分,创建内部类对象,必须依赖外部类对象
静态
不依赖外部类对象,可直接创建或通过类名访问,也可声明静态成员
Outer.Inner.静态成员
Outer.Inner in = new Outer.Inner();
Outer.Inner in = new Outer.Inner();
局部
定义在外部类的方法中,作用范围和创建对象的范围仅限当前方法中
局部内部类访问外部类局部变量时,因无法保障变量的生命周期与自身相同,所以修饰为final
隐藏类的信息、限制类的使用范围
匿名
没有类名的局部内部类
必须继承一个父类或实现一个接口
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
优:减少代码量,书写的思路流畅
劣:可读性较差
API:Application Programming Interface
Object类
概念
超类、基类,所有类的直接或间接父类,位于继承树的最顶层
任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承
Object类中所定义的方法,是所有对象都具备的方法
Object类型可以存储任何对象
作为参数,可接受任何对象
作为返回值,可返回任何对象
常用方法
public final Class<?> getClass(){}
返回引用中存储的实际对象类型。
应用:通常用于判断两个引用中实际存储对象类型是否一致
应用:通常用于判断两个引用中实际存储对象类型是否一致
public int hashCode(){}
一个对象的整数表现形式(整数型的名字)。
返回该对象的十进制的哈希码值。
哈希算法根据对象的地址或字符串或数字计算出来的int类型的数值。
哈希码并不唯一,可保证相同对象返回相同哈希码,尽量保证不同对象返回不同哈希码
返回该对象的十进制的哈希码值。
哈希算法根据对象的地址或字符串或数字计算出来的int类型的数值。
哈希码并不唯一,可保证相同对象返回相同哈希码,尽量保证不同对象返回不同哈希码
public String toString(){}
返回该对象的字符串表示(表现形式)。
可以根据程序需求覆盖该方法,如:展示对象各个属性值
可以根据程序需求覆盖该方法,如:展示对象各个属性值
public boolean equals(Object obj){}
默认实现为(this == obj),比较两个对象地址是否相同。
可进行覆盖,比较两个对象的内容是否相同
可进行覆盖,比较两个对象的内容是否相同
覆盖equals的顺序
比较两个引用是否指向同一个对象
判断obj是否为null
判断两个引用指向的实际对象类型是否一致
强制类型转换
依次比较各个属性值是否相同
protected void finalize() throws Throwable //了解(面试题中可能有坑)
当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
垃圾对象:没有有效引用指向此对象时,为垃圾对象
垃圾回收: 由GC销毁垃圾对象,释放数据存储空间
自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
手动回收机制:使用System.gc(); 通知JVM执行垃圾回收
包装类
概念
基本类型所对应的引用类型
Object可统一所有数据,包装类的默认值为null
包装类中实际上就是持有了一个基本类型的属性,作为数据的存储空间(Byte中有一个byte属性),还提供了常用的转型方法,以及常量,
既可以存储值,又具备了一系列的转型方法和常用常量,比直接使用基本类型的功能更强大
既可以存储值,又具备了一系列的转型方法和常用常量,比直接使用基本类型的功能更强大
包装类型中提供了若干转型的方法,可以让自身类型与其他包装类型、基本类型、字符串相互之间进行转换
转型方法
8种包装类型中,有6种是数字型(Byte、Short、Integer、Long、Float、Double),继承自java.lang.Number父类
java.lang.Number父类为所有子类分别提供了6个转型的方法,将自身类型转换成其他数字型。
byteValue();
shortValue();
intValue();
longValue();
floatValue();
doubleValue();
byteValue();
shortValue();
intValue();
longValue();
floatValue();
doubleValue();
parseXXX(String s) 静态转型方法,7种包装类型都有,除了Character,都可以通过String进行构建
parseByte("123");
parseShort("123");
parseInt("123");
parseDouble("123.45");
parseByte("123");
parseShort("123");
parseInt("123");
parseDouble("123.45");
valueOf(基本类型)、valueOf(字符串类型),静态转型方法,8种包装类型都有
Byte b1 = Byte.valueOf( (byte)10 );
Byte b2 = Byte.valueOf( "20" );
Byte b1 = Byte.valueOf( (byte)10 );
Byte b2 = Byte.valueOf( "20" );
注意:在使用字符串构建包装类型对象时,要保证类型的兼容,否则产生NumberFormatException
JDK5之后,提供自动装箱、拆箱,简化使用包装类的编程过程
Byte b4 = 40;//自动装箱,将基本类型直接赋值给包装类型,调用valueOf(byte b)
byte b5 = b4;//自动拆箱,将包装类型的值,直接赋值给基本类型,调用byteValue()
Byte b4 = 40;//自动装箱,将基本类型直接赋值给包装类型,调用valueOf(byte b)
byte b5 = b4;//自动拆箱,将包装类型的值,直接赋值给基本类型,调用byteValue()
自动装箱时,会调用valueOf方法,Byte、Short、Integer、Long,四种整数包装类型都提供了对应的cache缓冲区,将常用的256个数字提 前创建对象并保存在数组中,实现复用。即在区间的复用已有对象,在区间外创建新对象
String
概念
字符串是常量,创建之后不可改变
字符串字面值存储在字符串池中,可以共享
String s = "Hello"; 产生一个对象,保存在池中
String s2 = new String("World"); 产生两个对象,池、堆各一个
常用方法:参考API文档
0 条评论
下一页