Object类
- 基类 超类 所有类的直接或简介父类 位于继承树的最顶层
- 任何类 ,如果没显示继承某个类 都默认继承 Object类
- Object类中所定义的 方法 是所有对象都具备的方法
- Object 类型可以储存任何对象
-
- 作为参数,可以接受任何对象
- 作为返回值,可以返回任何对象
getclass()方法
- 后面加重将 class类型 反射的时候
- 返回 一个 类型
- 返回引用中储存的实际对象类型
- 应用:通常用于判断两个引用棕实际储存对象类型是否一致
public final class<?> getClass(){}
代码方便理解
用于判断两个引用棕实际储存对象类型是否一致
先写了一个 Student 类
public class Student{
private String name;
private int id;
//构造方法
public Student(String name,int id){
this.name = name;
this.id = id;
}
//get/set
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
接下来是测试类 TestStudent
public class TestStudent{
public static void main(String[] args){
Student s1 = new Student("a",18);
Student s2 = new Student("b",20);
//接下来就是使用 getClass 进行判断
Class class1 = s1.getClass();
Class class2 = s2.getClass();
if(class1==class2){
System.out.println("属于同一类型");
}else
System.out.println("不属于同一类型");
}
}
为什么 可以判断
因为 getClass()方法 所返回的 是 Class类 是一个类 对实例对象类进行比较
输出:
属于同一类型
hashCode() 方法
- 返回该对象的 哈希码值(int)
public int hashCode(){}
- 根据对象的地址或者字符串或数字使用 hash算法计算出来的 int类型的数值
- 一般情况下 相同对象返回相同哈希码
- 可以判断两个对象是否是同一个
这里的类还是 使用上面的
public class TestStudent{
public static void main(String[] args){
Student s1 = new Student("a",18);
Student s2 = new Student("b",20);
Student s3 = s1;
Student s4 = new Student("a",18);
System.out.println("s1="+s1.hashCode());
System.out.println("s2="+s2.hashCode());
System.out.println("s3="+s3.hashCode());
System.out.println("s4="+s4.hashCode());
}
}
输出
s1=1163157884
s2=1956725890
s3=1163157884
s4=356573597
这里可以很清楚的看到 s3 的哈希码值 是与 s1相同的
但是 s4 的 与 s1的 不相同
因为 s3 是 直接 等于 s1的
但是 s4 虽然实际参数与 s1相同 但是 s4 是 类重新 new 出来的 一个对象 所以 地址是不一样的
toString()方法
public String toString(){}
- 返回该对象的字符串表示对象 记住 是 直接 对对象进行打印的
- 可以根据程序需求覆盖该方法 如:展示对象的各个属性值
- 打印的是 带包的类的全名称@16进制的哈希值
Inner.demo05.Student@4554617c
Inner.demo05.Student@74a14482
以上分别是 s1 和 s2 的
4554617c 16进制 转化 10 进制就是 == 1163157884
地址是一样的
除了这个应用以外呢 还有可以根据需求 去重写 toString() 方法
例如 还是调用Student类
public class Student{
private String name;
private int id;
//构造方法
public Student(String name,int id){
this.name = name;
this.id = id;
}
public String toString(){
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
测试
System.out.println(s1.toString());
System.out.println(s2.toString());
输出:
Student{name='aaa', id=20}
Student{name='bbb', id=18}
可以看到改变了返回的方式
equals()方法
public boolean equals(Object obj){}
- 默认实现是 (this == obj),比较两个 对象的 地址 注意 这里比较的是 地址
- 可进行覆盖,比较两个对象内容是否相同
在 hashCode() 方法中我们 了解到 即使 属性相同的 对象 地址也是不一样的 所以比较输出出来的 还是 false
那我们是否可以 通过重写 equals 方法 来达到 两个类 属性相同 且 类也相同的 情况下 即使地址不同任然能输出 true
开始思考 首先要达到 类 和 属性都相同 我们就要 设立if语句去判断类和属性
if(this.getClass()==obj.getClass()){}
在多态中我们学习到 父类可以指向子类 但是无法使用子类的方法
那这里的 obj 编译类型其实是 Object 类 但是运行 则为 Student类(多态)
那这里 也可以这样写 先判断 obj 与 Student 是否存在父子关系 (instanceof)
if(obj instanceof Student){}
还有一个需求 就是 让obj对象 与 Student 对象进行属性的比较
使用的方法是 强制转换
if(obj instanceof Student){
Student s = (Student)obj;
if(this.name.equals(s.name)&&this.id==s.id){
return true
}
}
return false;
这里有个小疑问 后期解决
为什么 变化后可以直接调用属性? 后面写代码验证一下
这就写完了吗?
还没有 这里还需要 满足以下 以前有的 一些内容
比如 当 this对象 == obj 的时候 (地址也相同的情况)也应该输出 true
当 obj ==null 的时候 应该输出为 false
合起来一起写就是:
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj==null){
return false;
}
//if(this.getClass()==obj.getClass()){
if(obj instanceof Student){
Student s = (Student)obj;//父类转子类的 强制转换
//比较属性
if(this.name.equals(s.name)&&this.id==s.id){
return true;
}
}
return false;
}
finalize() 方法 (Java9 开始被弃用)
- 当对象被判定为 垃圾对象是 ,由 JVM 自动调用此方法 ,用以标记垃圾对象,进入回收队列
- 垃圾对象:没有有效引用指向此对象 为 垃圾独享
- 垃圾回收:由GC销毁垃圾对象啊你个 ,双方数据储存空间
- 自动回收机制 :JVM内存耗尽,一次性回收所有垃圾对象
- 手动回收机制:使用 System.gc();通知 JVM 执行垃圾回收
- 回收没有被引用的对象
重写finalize方法
@Override
protected void finalize() throws Throwable {
System.out.println(this.name+"对象被清理");
}
测试
Student s1 = new Student("aaa", 20);
Student s2 = new Student("bbb", 18);
new Student("ccc",20);
new Student("ddd",20);
System.gc();
System.out.println("回收完成");
输出:
回收完成
ccc对象被清理
ddd对象被清理
可以看到 被引用的 s1 s2 并没有被回收
但是 没有引用的 ccc ddd 被直接回收了
包装类
- 栈里存的是 基本类型(没有方法) 堆里是引用类型
- 为了让 基本类型可以使用方法 给 基本类型设计了所对应的引用数据类型 即为
基本类型的包装类
- 让基本类型 有属性 和 方法。
- Object 可以统一 所有的数据 , 包装类 是引用类型 所以 默认值是 null
| 基本数据类型 | 包装类型 |
| —————— | ————- |
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| boolean | Boolean |
| char | Character |
- 装箱跟拆箱
类型转换
-
- 装箱 :把 栈的基本类型 装到 堆里 转变成引用类型
- 拆箱 :把 堆里的引用类型 转变成 栈里的基本类型
Number类
`Byte、Integer、Long、Doublie、Short、Float 都是它的子类
方法:
拆箱方法:
引用类型转化为基本类型
| 返回值 | 方法名 |
| ———————- | ——————- |
| byte | byteValue () |
| abstract double | doubleValue() |
| abstract float | floatValue() |
| abstract int | intValue() |
| abstract long | longValue() |
| short | shortValue() |
装箱:
这以Integer为例
| 返回值 | 方法名(静态方法) |
| ——————— | ———————— |
| static Integer | valueOf(int i) |
代码:
public static void main(String[] args){
int i = 18;
//完成装箱 将 基本类型i 转变为 引用类型 integer
Integer integer = Integer.valueOf(i);
}
这里有个疑问
Integer.valueOf方法的返回值是一个类 这里相当于实例化了一个对象integer
既然是 对象 那为什么输出的时候 打印出来不是 地址 而是具体的值?
ai给出的答案是 : 当你打印integer时,实际上是调用了Integer类的toString()方法,该方法返回的是封装在Integer对象中的int值的字符串表示形式。
使用 hashCode() 方法 再次输出一次 也是无法输出 出哈希值
Integer类的hashCode()方法被覆盖,以返回封装的int值的哈希码,而不是对象本身的内存地址。
拆箱
代码
Integer i3 = Integer.valueOf(i3);
int i = i3.intValue();
//成功将 引用类型 Integer 转变为 基本类型 i
这里可以看到 是先 实例化对象后 再进行转换 所以类型转换针对的是对象
注意 : 这里以上的 代码都是 JDK1.5 之前的 装箱拆箱方法 JDK1.5之后 Java提供了自动装箱跟自动拆箱
自动装箱:
int age = 30;
Integer integer = age;
无需再调用方法 直接等于 默认装箱
自动拆箱:
int age = integer;
基本类型和字符串之间的转换
- 基本类型转化为字符串
-
- 使用 +号
int i =150;
String s1 = i+"";
-
- 使用 Integer 中的 toString()方法
String s2 = Integer.toString(i);
这里 引用对象 不是Integer的情况下 也是直接使用了 Integer的方法
原因:toString()是 Integer的一个静态方法 直接调用并将 i直接转变成 字符串 然后 赋值给 s2
小拓展 toString()的重载方法
Integer.toString(int i ,int radix);
把 int i 当 radix 进制返回
String s2 = Integer.toString(i,16);//把 i 以 16 进制返回
-
- 实例化对象后 使用 toString()方法
区别于 第二种方法 这种方法
String s1 = new Integer(n).toString();
-
-
- new Integer(n):首先创建了一个 Integer 类的实例。
- .toString():然后调用这个实例的 toString 方法,返回封装的 int 值的字符串表示。
- 创建一个新的 String 对象 s1,并将从 Integer 实例得到的字符串赋值给它。
-
- 字符串转化为基本类型
String str = "150";
-
- 使用 Integer.parseXXX()方法 是一个静态方法可以直接调用
int n2 = Integer.parseInt(str);
这里要注意以下 如果 str 中存在不是 int 类型的字符
那么就会出现异常
Exception in thread "main" java.lang.NumberFormatException: For input string: "150c"
数字格式化异常
- boolean :字符串 形式 转成 boolean 基本类型
注意 : 这里有点说法
-
- 如果 字符串为 “true” 那么 就是 true 如果不是 “true” 就都是 “false”
String str = "true";
boolean b1 = Boolean.parseBoolean(str);
System.out.println(b1);
true
String str = "1";
boolean b1 = Boolean.parseBoolean(str);
System.out.println(b1);
false
整数缓冲区
- Java预先创建了 256 个常用的整数包装类型对象
- 再实际应用当中 对已创建的对象进行复用
在了解 整数缓冲区 之前 我们需要重新看一下 自动装箱的 class文件
在 class 文件中 很清楚的看到
自动装箱 是通过 Integer.valueOf() 静态方法 来实现的
Integer integer = 100;
// Integer integer = Integer.valueOf(100);
那么什么是整数缓冲区 ?
我们通过一个问题进行引入
Integer integer3 = Integer.valueOf(100);
Integer integer4 = Integer.valueOf(100);
System.out.println(integer3==integer4);//true ?
Integer integer5 = Integer.valueOf(200);
Integer integer6 = Integer.valueOf(200);
System.out.println(integer5==integer6);//false ?
在这里 当int i = 100 的时候比较相同 输出的是 true
当int i = 200 的时候比较相同 输出的是 false
为什么?
我们通过查看 valueOf() 方法的源码 了解到
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerCache.low = -128;
IntegerCache.high = 127;
IntegerCache.cache[(high - low)+1];
当 i >= -128 && i <= 127时 返回值 是一个 数组内的元素 即为 int 类型
除非 就是返回一个 对象 这时候输出的 就是一个 地址
所以当 i = 200时 对比才会 输出 false.
而 这个 [-128 , 127] 的区间 就是 整数缓冲区
在 区间内返回 int 类型的 值
在 区间外 返回 对象
String类
- 字符串是常量 , 创建之后不可以改变
这里的不可改变的意思是:
比如 我现在写了一行代码
String name = "luojinyuan";
这里定义了一个String类变量 name
在内存中 应该是 这样子的 :
然后 我将 变量 name 改变一下
name = "罗锦源";
这时候 内存 会变成这样:
可以看到 原来的值 luojinyuan 并没有改变 而是新建了一个值
而 luojinyuan没有指向 利用 System.gc()就可以清理掉
所以 可以看到 字符串不会改变 但变量可以改变 (重新建一个值)
- 字符串字面值存储在字符串池中 ,可以共享
这时候 我们再建一个变量name2等于 罗锦源 内存又该如何?
String name2 = "罗锦源";
这时候的内存应该是:
可以看到 在栈中 新建了一个 引用对象地址 并且在 常量池中 都指向相同的 对象 罗锦源
所以 并不会 在常量吃中 再新建一个字符串一模一样的常量 而是重新建了一个 引用地址
- 另外一种创建字符串的方式
String str1 = new String("str");
String str2 = new String("str");
这时候 栈中会产生相应的 地址 指向堆中的 新建对象 然后再指向常量池中的值
我们比较分两种方法比较一下 str1 和 str2
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
输出:
false
true
首先说说为什么 输出 是 false
因为 用 ==比较对象时 比较的是 对象地址 再内存图中 可以清楚的看到 新建了 两个对象分别表示 str1 str2
所以输出 false
那为什么用 equals方法输出就是 true
因为 再 String类中 equals被重写了 比较的是 字符串是否相同
常用方法
- 返回 字符串的长度
public int length();
使用:
String name = "java是世界上最好的语言java ";
System.out.println(name.length());
- 根据下标获取字符
public char charAt(int index);
使用:
System.out.println(name.charAt(3));
System.out.println(name.charAt(name.length()-1));
注意防止下标越界
- 判断是否包含某个字符
public boolean contains(String str);
输出:
System.out.println(name.contains("是"));
- 将字符串转化为数组
public char[] toCharArray();
使用:
char[] a = name.toCharArray();
System.out.println(Arrays.toString(a));
- 查找 str 首次出现的下标
存在 , 返回该下标
不存在 ,返回 -1
public int indexOf(String str);
使用:
System.out.println(name.indexOf("java"))
输出:0 输出 是首个字符的位置
拓展:
从 第 index 个数开始 查找str
public int indexOf(String str,int index);
使用:
System.out.println(name.indexOf("java",4))
输出:13
从第四个开始查找 java 找到后 在字符下标 13的位置
- 查找字符串再当前字符中最后一次出现的下标索引
public int lastIndexOf(String str);
使用:
System.out.println(name.lastIndexOf("java"));
输出:13
- 去掉字符串前后的空格
public String trim();
使用:
String name2 = name.trim();
System.out.println(name2);
输出:java是世界上最好的语言java
这里要注意 输出出来的 是字符串
- 将小写转成大写
public String toUpperCase();
使用:
String name3 = "hello,World";
System.out.println(name3.toUpperCase());
输出:HELLO,WORLD
- 判断字符串是否以 str 结尾(开头)
public boolean endWith(String str);//结尾
public boolean startWith(String str);//开头
使用:
System.out.println(name3.endWith("World"));
public boolean startWith("Hello")
输出:true true
- 将旧字符串替换为新字符串
public String replace(char oldChar,char newChar);
使用:有一个接口的形参 可以直接用字符串 不只是用字符
name.replace("Java","php").sout
输出:php是世界上最好的语言php
- 根据str做拆分
public String[] split(String str);
使用
String say = "java is te best propraming language,java xiang";
String[] s = say.spilt(" ");
Arrays.toString(s).sout
输出:[java, is, te, best, propraming, language,java, xiang]
拓展
比如 可以看到 上面的 s替换的时候 ,跟前面的连在一起了 我想将,也隔开
可以这样写
String[] s = say.spilt("[ ,]");
在[]里面写入 一个空格和 , 意思是 遇到 空格 或 ,的时候 进行拆分
如果是 双空格也拆分的话
可以在 []后面 加上 一个 +号
String[] s = say.spilt("[ ,]+");
- equals 和 compareTo 两种比较大小的方法
首先 声明一点
两者的返回值不同
equals 的返回值是 boolean
compareTo 的返回值是 int
-
- equals
String s1 = "hello";
String s2 = "HELLO";
System.out.println(s1.equalsIgnoreCase(s2));
equalsIgnoreCase() 这个方法 可以让 equlas在比较的时候忽略大小写
-
- compareTo
String s3 = "abc";
String s4 = "xyz";
String s5 = "abcxyz";
System.out.println(s3.compareTo(s4));
这个代码其实是 做减法
s3 首字母在 字符表中的 位置 比如 上面代码中 的 a 97
减去
s4 首字母在 字符表中的 位置 比如 上面代码中 的 x 120
输出 :-23
加入 首字母相同 那么 就比较下一位 以此类推
特殊情况:
System.out.println(s3.compareTo(s5));
这里 前面都一样 但是 s3 没有了 s5 还有
这里 就不比较 在 字符表中的 值了
这里比较 长度
所以输出的是 3-6
输出:-3
- 截取字符
public String substring(int beginIndex,int endIndex)
针对 字符串截取字符
String name = "luojinyuan";
name.substring(1);
从下标是 1 的字符开始截取字符串到最后
省略了后面的参数 endIndex 的意思是 截取到 最后一个的字符下标 可以自定义截取 默认为最后一个
输出:uojinyuan
- 可变长字符串
这两是 类 不是方法
StringBuffer:可变长字符串,JDK1.0提供,相对StringBuffer运行效率慢,线程安全
StringBuilder:可变长字符串,JDK5.0提供,运行效率块,线程不安全,单线程建议用这个
这两个类 与 String 的区别
-
- 效率比 String 高
- 比 String 节省内存
代码验证运行效率
String
long start = System.currentTimeMillis();
String string = "";
for (int i = 0; i < 99999; i++) {
string+=i;
}
System.out.println(string);
long end = System.currentTimeMillis();
System.out.println("用时"+(end-start));
输出:用时20272
StringBuffer
long start = System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 99999; i++) {
stringBuffer.append(i);
}
System.out.println(stringBuffer);
long end = System.currentTimeMillis();
System.out.println("用时"+(end-start));
输出:用时16
使用方法:
首先 使用类的方法 先 实例化类
StringBuffer sb = new StringBuffer();
- append();追加字符
sb,append("java是 世界上最好的语言");
System.out.println(sb.toString());
- insert();在某个位置添加字符
sb.insert(0,"你好 Java,");//在 下标0 的位置添加
System.out.println(sb.toString());
- replace();替换
sb.replace(0,7,"Hello java");
System.out.println(sb.toString());
这里要注意 这里的区间是 [0,7) 含头不含尾
- delete();删除
sb.delete(0,6);
System.out.println(sb.toString());
这里要注意 这里的区间是 [0,6) 含头不含尾
这里拓展一个 清空可变字符串的办法
sb.delete(0,sb.length());
System.out.println(sb.toString());
还是用 delete(); 进行清空
BigDecimal
引入:
public static void main(String[] args) {
double d1 = 1.0 ;
double d2 = 0.9 ;
System.out.println(d1-d2);
}
}
输出:0.09999999999999998
不等于 0.1
因为 double 有精度问题 存储的值不一定是 1.0 可能是 0.99999999999
这里引入一个 类
BigDecimal 可以对浮点数进行精准的运算
前面也说过 这个类用于 银行等地方的运算
方法
浮点数的运算
还是那句话 使用类前 先 实例化
BigDecimal b1 = new BigDecima("1.0");//这里注意以下 要用字符串 字符串最为精确
BigDecimal b2 = new BigDecima("0.9");
- 加法add();
BigDecimal r1 = b1.add(b2);
System.out.println(r1);
- 减法subtract();
BigDecimal r2 = b1.subtract(b2);
System.out.println(r2);
- 乘法muliply();
BigDecimal r3 = b1.muliply(b2);
System.out.println(r3);
- 除法divide(); 注意以下异常
BigDecimal r3 = b1.muliply(b2);
System.out.println(r3);
这是 1.0/0.9 是除不尽的 会报异常
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
这里很好解决 就是 divide(); 这个方法中 有一个 精确到小数的参数
public BigDecimal divide(BigDecimal bd,int scal,RoundingMode mode){}
scal:指定精确到小数点后几位
mode:指定小数部分的取舍模式,经常采用四舍五入 如下
BigDecimal divide = b1.divide(b2,2,BigDecimal.ROUND_HALF_UP);
这里的意思是 b1/b2 精确到小数点后两位 ,BigDecimal.ROUND_HALF_UP 的意思是 四舍五入
这样就不会报异常了
- 列式编程 连续运算
BigDecimal r2 = new BigDecimal("1.0")
.subtract(new BigDecimal("35"))
.add(new BigDecimal("65"))
.multiply(new BigDecimal("59"))
.divide(new BigDecimal("11"),2,BigDecimal.ROUND_HALF_UP);
System.out.println(r2);
输出:166.27
Date
- Date表示 瞬间 精确到毫秒
- 现在大部分的方法 都被 Calendar
- 不太全面,国际化问题 所以被取代
构造方法 无参:
public Date();
创建一个 Date对象 当前的时间 精确到毫秒
打印
Date date1 = new Date();
System.out.println(date1);
直接打印的话 格式 是这样的
输出:Mon Jun 03 20:31:04 CST 2024
所以一般用这个方法来打印toLocalString();
System.out.println(date1.toLocaleString());
不过呢 这个方法已经过时了但是仍然可以使用
上面的是 今天 的 写一个昨天的此时此刻
Date date2 = new Date(date.getTime()-(24*60*60*1000));
System.out.println(date2.toLocaleString());
getTime();返回的是 从 1970年开始 到现在的毫秒数
方法
- after(); 和before(); 判断时间的先后 返回值是布尔值
boolean after = date.after(date1);
System.out.println(after);
输出:true
date 在 date1 之后
before();同理
- compareTo(); 比较 时间减法 返回值是int
int i = date.compareTo(date1);
System.out.println(i);
输出:1
- equals(); 比较是否相等 返回值是布尔值
boolean equals = date.equals(date1);
System.out.println(equals);
输出:false
Calendar
- Calendar 提供了获取或设置各种日历的方法
- 构造方法
protected Calendar();
注意这里的修饰符 是protected所以无法直接创建对象
方法
- 静态方法:
获取时间
Calendar calendar = Calendar.getInstance();
- 打印
我们先看使用 toString();方法打印
System.out.println(calendar);
输出:
java.util.GregorianCalendar[time=1717418897886,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2024,MONTH=5,WEEK_OF_YEAR=23,WEEK_OF_MONTH=2,DAY_OF_MONTH=3,DAY_OF_YEAR=155,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=8,HOUR_OF_DAY=20,MINUTE=48,SECOND=17,MILLISECOND=886,ZONE_OFFSET=28800000,DST_OFFSET=0]
看不懂
所以不能直接输出
那我们如何打印
我们先 使用 getTime(); 方法 将它变成Date再使用 toLocalString(); 方法进行打印
System.out.println(calendar.getTime().toLocalString());
输出:2024-6-3 20:48:17
还有一种 是 打印毫秒值
System.out.println(calendar.;getTimeInMillis());
输出:1717418897886
- 获取时间信息 get();
在 Calendar 类中 提供了很多常量
如 YEAR MONDAY MONDAY
int i = calendar.get(Calendar.YEAR);
int i1 = calendar.get(Calendar.MONDAY);
int i2 = calendar.get(Calendar.MONDAY);
int i3 = calendar.get(Calendar.HOUR_OF_DAY);
int i4 = calendar.get(Calendar.MINUTE);
int i5 = calendar.get(Calendar.SECOND);
System.out.println(i+"年"+(i1+1)+"月"+i2+"日"+i3+":"+i4+":"+i5);
输出:2024年6月3日20:48:17
这里有个点 就是 在 HOUR中 有两个
HOUR:12小时
HOUR_OF_DAY:24小时
还有就是
可以看到 MOUTH 月中 是从 0 开始的
所以要+1
- 修改时间 set();
Calendar calendar1 = Calendar.getInstance();
calendar1.set(Calendar.DAY_OF_MONTH,5);
System.out.println(calendar1.getTime().toLocaleString());
输出:2024-6-5 20:59:41
这里是直接 将 Calendar.DAY_OF_MONTH 改成了 5
- 添加 add();
calendar1.add(Calendar.HOUR_OF_DAY,1);
System.out.println(calendar1.getTime().toLocaleString());
输出:2024-6-5 21:59:41
这里是将Calendar.HOUR_OF_DAY 增加了 1
- 获取时间的最大值 或 最小值 比如 一个月中的最后一天 getActualMaximum(); getActualMinimum();
int actualMaximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
System.out.println(actualMaximum);
输出:30
SimpleDateFormat
- 以语言环境有关的方式格式化和解析日期的具体类
- 进行格式化(日期——>文本)
- 解析(文本——>日期)
- 常用时间模式字母
字母 | 日期或时间 | 实例 |
y | 年 | 2019 |
M | 年中月份 | 08 |
d | 月中天数 | 10 |
H | 1天中小时数(0-23) | 22 |
m | 分钟 | 16 |
s | 秒 | 59 |
S | 毫秒 | 367 |
- 实例化的时候 定义时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
- 然后定义一个 Date 类 试试
Date date = new Date();
- 格式化 Date 将日期变成字符串 format(); 返回值是String类型
String format = sdf.format(date);
System.out.println(format);
输出:2024年06月03日 21:18:32
- 解析 将字符串转化为日期 返回值是Date类型
Date parse =sdf.parse("2024年06月03日 20:10:06");
System.out.println(parse.toLocaleString());
输出:2024-6-3 20:10:06
如果 这里输入的字符串不是 上面 sdf 所定义的格式 就会异常
解析失败异常
Exception in thread "main" java.text.ParseException: Unparseable date: "202406月03日 20:10:06"
System
- 系统类,主要用于获取系统的属性数据和其他操作,构造方法私有
- 大部分方法是 静态方法 所以不需要实例化 直接调用
方法
- 复制数组
static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
src:原数组 要复制哪个数组
srcPos:从哪个位置开始复制 0
dest:目标数组
destPos:目标数组的位置 从哪里开始放复制的东西
length:复制的长度
int[] arr ={20,18,15,8,35,26,45,30};
int[] dest = new int[arr.length];
System.arraycopy(arr,0,dest,0,arr.length);
- 获取当前系统时间,返回毫秒值
static long currentTimeMillis();
之前在 可变长字符串里面使用过这个来测试运行的时间
long start = System.currentTimeMillis();
String string = "";
for (int i = 0; i < 99999; i++) {
string+=i;
}
System.out.println(string);
long end = System.currentTimeMillis();
System.out.println("用时"+(end-start));
start是记录 还未运行下面程序时 的一个 时间
end 是记录 运行结束后的一个时间
差值就是用时
- 建议JVM赶快启动垃圾回收器回收垃圾
static void gc();
这里具体看 Object类中的 finalize()方法
- 退出jvm,如果参数是 0 表示正常突出 非0则是异常推出 jvm
static void exit(int status);
退出Jvm虚拟机以后 后续的程序将不再运行
System.exit(0);