无分类
-
获取从1970年1月1日0时0点0分到现在所经历的毫秒:
System.currentTimeMillis();
-
链式编程:使用方法返回的对象继续进行编程
-
遇到
new
关键字就会在堆内存中开辟空间,并且对属性进行默认初始化赋值 -
获取当前路径:
System.getProperty("user.dir");
-
Java 标准库中有一些类型,已经不再推荐使用,仅因为兼容旧代码才保留下来。下面哪些是遗留的集合:
- Stock
- Vector
- RandomAccess
- AbstractList
- Properties
- HashTable
-
main函数
public
: 被jvm
调用,访问权限足够大static
: 被jvm
调用,不用创建对象,直接类名访问void
: 被jvm
调用,不需要给jvm
返回值main
: 一个通用的名称,虽然不是关键字,但是被jvm识别String[] args
: 以前用于接受键盘录入的- forEach遍历,例:
List<Integer> l = new ArrayList<>();
l.add(1);
l.add(10);
l.add(2);
l.add(4);
l.add(3);
l.add(8);
l.add(7);
l.add(6);
l.forEach((Integer i) -> {
System.out.println("xixixi" + i);
});
- 静态代码块
- 加载类的时候会自动执行,且只执行一遍
static {
}
JDK
jdk11
后同时判断字符串为null
或""
:isBlank();
jdk8
之后再接口方法前可以加上default
表示已经默认实现,不必在实现类中强制实现
循环
分支语句switch
最好加上
default
跳转
Java是可以实用类似于汇编的标号的,例:
a: for(int i = 1;i <= 10;i++){
System.out.println(i = + i);
b: for(int j = 1;j <= 10;j++){
System.out.println(j = + j);
break a;
}
}
隐式转换
byte
和char
short
和char
之间需要进行强转- 隐式转换(自动转换): 小的数据往大的类型转换时,没有风险,Java会自动帮我们进行转换
byte
short
char
在进行运算时会自动转换为int再开始运算
JRE和JDK
jre
包含已经写好的Java代码(jvm
和核心类库
),jdk
包含翻译和执行等等开发工具- 真正执行调用Java程序时使用
jvm
及Java的跨平台
工具类
Math.ceil(double)
: 向上取整Math.floor()
: 向下取余
可变参数
概述、特点
- 在底层看也是一个数组
- 格式:
修饰符 返回类型 方法名(参数类型...变量名)
- 可变参数要放在后边
例:
public class Test {
public static void main(String[] args) {
System.out.println(getSum(1, 2, 3, 4, 5, 6));
}
public static int getSum(int...intArr) {
int sum = 0;
for (int i : intArr) {
sum += i;
}
return sum;
}
}
枚举
表示一些固定的值
好处
- 限制参数传递
- 可以见名知意
定义格式
public enum 枚举类名 {
枚举项1, 枚举项2, 枚举项3...;
}
特点
- 所有的枚举类都是
Enum
的子类 - 每一个枚举项其实都是该枚举类的一个对象
- 枚举类中可以定义成员变量
- 枚举类中的第一行必须是枚举项,如果后面没有其他东西,分号可以省略
- 枚举类中也可以有构造方法,且该构造方法必须是
private
的,且默认也是private
的 (限制在其涛涛涛涛类中创建对象) - 枚举类中可以有抽象对象,但枚举项必须重写该方法
方法
- name(): 获取名称
- ordinal(): 获取枚举项在枚举类中的索引
- compareTo(): 返回索引值的差
- toString(): 返回索引值的名称
- valueOf(): 返回指定名称的枚举项的索引值
- values(): 返回所有的枚举项
public enum SeasonEnum {
SPRING("春"),
SUMMER("夏"),
AUTUMN("秋"),
WINTER("冬");
public String name;
private SeasonEnum(String name) {
this.name = name;
}
}
public class EnumTest {
public static void main(String[] args) {
System.out.println(SeasonEnum.SPRING);
System.out.println(SeasonEnum.SPRING.name());
System.out.println(SeasonEnum.SUMMER.ordinal());
System.out.println(SeasonEnum.SUMMER.compareTo(SeasonEnum.WINTER));
System.out.println(SeasonEnum.AUTUMN.toString());
System.out.println(Enum.valueOf(SeasonEnum.class, "SPRING"));
SeasonEnum[] values = SeasonEnum.values();
System.out.println(SeasonEnum.SPRING.name);
}
}
栈区、堆区、方法区
堆
存线程操纵的对象(以对象的形式存放) 被所有线程共享
特点
- 存储的全都是对象,每个对象包含一个与之对应的class信息(class的目的是得到操作命令)
- jvm只有一个堆区(heap)被所有线程共享,堆区中不存放基本类型和对象引用,只存放对象本身
栈
- 栈中存放基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
- 每个栈中的数据(基础数据类型和对象引用)都是私有,其余栈不能访问
- 栈分为三个部分:
- 基本类型变量区
- 执行环境上下文
- 操作指令区
方法区
存放线程所执行的字节码指令
- 又叫静态区,被所有线程共享,方法区包括:
- 所有的class资源
- 所有的static资源
- 方法区中包含的是在整个程序中唯一的元素,如:
- class
- static
UUID
可以生成随机且"全球唯一"的
UUID
对象
面向对象编程
面向对象的三个特征:
封装
,继承
,多态
封装
继承
- 继承只能引用父类的非私有变量和方法 注:可以使用私有对象,例:
getter
和setter
方法 - 子类中所有构造方法默认都会访问父类中无参的构造方法
- 子类会继承父类中的数据,可能还会使用父类的数据,所以,子类初始化之前,一定要先完成父类数据的初始化
- 每一个子类构造方法的第一条语句默认都是
super()
继承优点
通过继承,提升代码的复用性和维护性
继承缺点
代码的耦合度提高,父类发生改变,子类不得不一起发生改变
成员变量的访问特点
- 就近原则,谁离我近就用谁
super关键字
super
可以理解为对父类的引用
super关键字和this关键字的区分
this
关键字代表调用该方法的对象,一般我们是在当前类中使用this
,所以我们常说this
是对本类对象的引用super
关键字代表父类存储空间的标识,可以理解为对父类对象的引用
创建一个子类时
注: 如果没有写
super()
系统会自动给我们补一个super()
方法重写
- 子类中那个出现的和父类中一模一样的方法声明
@Override
检查子类中重写父类方法时语法是否正确
方法重写和方法重载的区别
方法重载
- 在同一个类
- 参数类型、个数、顺序等不同
- 方法名相同
方法重写
- 子类中定义了和父类中方法声明一摸一样的方法
多态
多态的条件
- 子类重写父类的方法
- 有继承或实现
- 父类引用指向子类对象
多态中成员访问特点(有父类引用指向成员对象)
- 例:
public class Anamal {
public int age = 40;
public void eat() {
System.out.println("动物吃东西");
}
}
public class Cat extends Animal {
public int age = 20;
public int weight = 10;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉老鼠");
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Cat();
}
}
- 成员变量: 编译看左边(父类中有没有),执行看左边(父类中有没有) 例:
System.out.println(a.weight); // 父类中没有,会报错
- 成员方法: 编译看左边(父类中有没有),执行看右边(子类中有没有) 例:
a.eat(); // 会输出 "猫吃鱼"
- 根本原因: 方法可以重写,变量不可以
多态本质
将子类的对象伪装成父类
多态的好处
提高代码的扩展性
多态应用场所
设置形参时,最好写对象的父类
转型
向上转型
从子到夫
父类引用指向子类对象
- 例:
Animal a = new Cat();
向下转型
从父到子
父类引用转为子类对象
- 例:
Animal a = new Cat();
Dog d = (Dog) a;
- 向下转型前要进行类型判断: 使用
instanceof
关键字
修饰符
权限修饰符
状态修饰符
final
概述
final
是最终的意思,可以修饰成员方法、成员变量、类final
修饰的方法不可被重写final
修饰的类为最终类,不可被继承
final修饰基本类型变量
特点
- 不可重新进行赋值
final修饰引用类型的成员变量
特点
- 地址值不变,但是属性值是可以重新赋值的(
final
的对象中的成员变量值可以改变,但是不能将其重新new) - 被
final
修饰的字符串不能重新赋值,因为每一次重新赋值都相当于重新赋地址
static
概述
静态的意思,可以修饰成员方法、成员变量
static特点
- 多了一个调用方式(
类名.
) - 被
static
所修饰的成员会被该类的所有对象共享
static修饰的特点
- 被类的所有对象共享,这也是我们判断是否适用静态关键字的条件
- 可以通过类名调用,当然,也可以通过对象名调用,推荐使用类名调用
static修饰成员的访问特点
- 非静态的成员方法可以使用本类中所有的静态内容和非静态内容
- 静态的成员方法只能访问静态的成员变量
static应用
- 工具类以私有方式构造,方法设计为静态,就只能通过
类名.
的方式调用,不能创建对象 - 为什么构造方法要私有化?
- 工具类中所有的方法都是静态方法
- 工具类中不会存在成员变量
抽象类
概述
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类,抽象类不可实例化,抽象类中不一定有抽像方法,可以有非抽象方法(可以有空参和有参构造方法-用于子类初始化)
特点
- 抽象方法只能定义在抽象类中
- 语法: 使用
abstract
关键字修饰的方法 - 作用: 给子类提要求
- 语法: 使用
- 抽象类不可实例化
- 抽象类的子类不是抽象类
抽象类的成员特点
- 抽象类的成员变量: 以前怎么写现在怎么写
- 抽象类的成员方法: 可以是普通方法,也可以是抽象方法
- 抽象类的构造方法: 存在,但不能实例化
其他
- 抽象类和普通类没有任何区别
static
和abstract
是冲突的(static
修饰的方法是静态方法,其可以直接被类所调用。而abstract
修饰的方法为抽象方法,即无方法体的方法,不能够被直接调用,需要在子类或实现类中去编写完整的方法处理逻辑后才能使用)
Object
- 退出虚拟机
exit();
- 获得的是自 1970-1-01 00:00:00.000 到当前时刻的时间距离, 类型为
long
:System.currentTimeMillis()
Ststem.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
: 复制数组,将指定源数组src
中的数组从指定位置srcPos
复制到目标数组dest
的指定位置destPos
。阵列组件的一个子序列被从通过引用的源阵列复制src
被引用的目标阵列dest
。复制的组件数量等于length
参数。- 父类的
toString()
方法,返回的结果是:包名.类名+"@"+对象的地址
,注: 只要一个对象能打印出,不是地址值,就说明这个类一定重写过toString()
方法
包装类
包含
int
Integer
long
Long
float
Float
double
Double
char
Character
boolean
Boolean
Integer特性
- 自动装箱: 基本类型 -> 包装类型
- 自动装箱时,数据大小在 [-128, 127] 范围内,不会重新创建对象,所以是同一个地址
- 原理: 编译器调用
valueOf
将原始类型值转换成对象
- 自动拆箱: 包装类型 -> 基本类型
- 原理: 编译器通过调用类似于
intValue()
、doubleValue()
等方法将对象转换成原始类型值
- 原理: 编译器通过调用类似于
BigDcimal
- 涉及与小数有关时推荐使用
- 提供了方法可以进行四则运算
BigDecimal.divide()
可以保留指定小数位(, 位数, RoundingMode.HALF_UP)
Objects
Objects.toString(Object o, String nullDefault);
: 若对象o
为空,返回nullDefault
,实际上是调用了底层的o.toString();
Objects.equals(Object o1, Object o2);
: 判断两个对象是否相同,相同返回true
,不同返回false
,实际调用了底层的o1.equals(o2);
Objects.inNonNull(Object o)
: 判断一个对象是否为null
,实际上调用了底层的if(o != null)
Arrays
概述
Arrays
是一个对数组进行操作的工具类(工具类全是静态的),提供了查找、排序等功能,详见API。
异常
概述
- 程序出现了不正常的情况,程序在执行过程中,出现的非正常的情况,最终会导致
JVM
的非正常停止 - 注: 语法错误不算在异常体系中
异常体系
Error
: 严重问题,通过代码无法解决Expection
:RuntimeExpection
: 及其子类- 除
RuntimeExpection
之外所有的异常
编译时异常和运行时异常
- 编译时异常: 在编译成
class
文件时必须要处理的异常,也称之为受检异常 - 运行时异常: 在编译成
class
文件时不需要处理,在运行字节码文件时可能出现的异常,也称之为非受检异常
- 注: 运行时异常可以不用写在方法声明中
虚拟机默认处理异常的处理方法
- 当代码出现乐异常,那么就在这里创建了一个异常现象
- 首先会看,程序中那个有没有自己处理异常的代码
- 如果没有,交给本方法的调用者处理
- 最终这个异常会交给虚拟机默认处理
JVM默认处理异常做了哪几件事情
- 将异常信息以红色字体展示在控制台上
- 停止程序运行,哪里出现异常,那么程序就在哪里停止
异常处理方式
throws声明异常
告诉调用者,你调用我,可能会出现这样的异常
- 如果方法中没有出现异常,那么正常执行
- 如果方法中出现了异常,将这个异常交给调用者处理
- 如果方法中有编译时异常,则必须手动声明异常
throw抛出异常
该异常创建之后,暂时没有手动处理,抛给了调用者处理,下面的代码不会再执行了
抛出处理异常的意义
- 在方法中,当传递的参数有误,没有进行下去的意义了,则采取抛出处理,表示让该方法结束运行
- 钙塑调用者方法出现了问题
try … catch 好处
程序还可以继续运行
try
不可缺少catch finlly
不可缺少
Throwable的成员方法
getMessage
: 显示异常的信息toString
: 显示异常的第一行printStackTrace
: 打印异常,字体是红色的
自定义异常
为了让异常信息更加见名知意
- 例:
// 异常类
public class AgeOutOfBoundaryException extends RuntimeException {
public AgeOutOfBoundaryException() {
}
public AgeOutOfBoundaryException(String message) {
super(message);
}
}
// 实体类
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 0 || age >= 100) {
throw new AgeOutOfBoundaryException("请确认年龄输入正确");
}
this.age = age;
}
}
// 测试类
public class ExceptionTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Student student = new Student();
String errorMas = null;
System.out.print("请输入姓名: ");
String name = sc.next();
student.setName(name);
System.out.print("请输入年龄: ");
int age = sc.nextInt();
try {
student.setAge(age);
} catch (AgeOutOfBoundaryException e) {
errorMas = e.toString();
}
if (java.util.Objects.equals(null, errorMas)) {
System.out.println("输入年龄为: " + age);
} else {
System.out.println("输入出错: " + errorMas);
}
}
}
日期类
计算机中的起始时间:
1970 年 1 月 1 日 00:00:00
Date类
构建方法
- 无参: 表示当前电脑时间(注意时差)
- 有参: 可以指定一个时间,参数为毫秒值,类型为
long
常用方法
getTime()
: 获取当前时间的毫秒值setTime(long)
: 更改当前Date
对象中的时间
SimpleDateFormat
概述
可以对
Date
对象进行格式化和解析,注: 解析不是为了打印,是为了方便计算
常用字母及其对应关系
y
– 年 (yy
表示当前天所处的年份YY
表示本周所处的年份,跨年周表示下一年)M
– 月d
– 日H
– 时m
– 分s
– 秒
具体方法
-
format()
: 以某格式显示
ge);
} else {
System.out.println("输入出错: " + errorMas);
}}
}
# 日期类
> 计算机中的起始时间: `1970 年 1 月 1 日 00:00:00`
## Date类
### 构建方法
* 无参: 表示当前电脑时间(注意时差)
* 有参: 可以指定一个时间,参数为毫秒值,类型为 `long`
### 常用方法
* `getTime()`: 获取当前时间的毫秒值
* `setTime(long)`: 更改当前 `Date` 对象中的时间
## SimpleDateFormat
### 概述
> 可以对 `Date` 对象进行格式化和解析,注: 解析不是为了打印,是为了方便计算
### 常用字母及其对应关系
* `y` -- 年 (`yy` 表示当前天所处的年份 `YY` 表示本周所处的年份,跨年周表示**下一年**)
* `M` -- 月
* `d` -- 日
* `H` -- 时
* `m` -- 分
* `s` -- 秒
### 具体方法
* `format()`: 以某格式显示
* `parse()`: 将某格式转换成 `Date` 格式