09 -- 10. java学习 -- static关键字、内部类、Object类、String类、其他实用类

09 – 10. java学习 – static关键字、内部类、Object类、String类、其他实用类



一、static关键字

static关键字是静态修饰符,可以用来修饰方法、变量。一旦类里面的成员被static关键字修饰后,当前类创建的所有对象都会共享这些静态资源。

1. static关键字的使用

  1. 类成员被static关键字修饰,该类创建的所有对象都共享这些静态资源
// 在类中定义静态成员变量
public class StaticDemo01 {
    public static int num = 100;

    public void change() {
        num = 10;
    }
}
// 测试类
class TestStatic {
    public static void main(String[] args) {
        StaticDemo01 staticDemo01 = new StaticDemo01();
        StaticDemo01 staticDemo02 = new StaticDemo01();

        System.out.println(staticDemo01.num);   // 100
        System.out.println(staticDemo02.num);   // 100

        staticDemo01.change();

        System.out.println(staticDemo01.num);   // 10
        System.out.println(staticDemo02.num);   // 10

        // 静态进行调用推荐通过类名调用
        System.out.println(StaticDemo01.num);   // 10

    }
}
  1. 静态资源加载早于非静态资源,因此对于静态资源的访问不能使用this关键字和super关键字
// 例子:
public class StaticDemo01 {
    public static int num = 100;

    public void change() {
        num = 10;
		// this.num 会报错     
		// this指代的是当前方法的调用者对象,静态加载早于对象,因此不能用this。
		// super同理
    }
}
  1. 静态方法里可以访问静态资源,但是不能访问非静态资源
// 例子:
public class StaticDemo1 {

    public static int num = 100;
    
    public void test02(){
        System.out.println("这是非静态的方法test02");
    }

    public static void test03(){
        System.out.println("这是静态的方法test03");
    }

    public static void test01(){
        // this.num; 
        // this指代当前方法的调用者对象,此时调用对象可能还不存在
        System.out.println(num); // 可以访问静态的num
        test03(); // 静态方法test03可以访问的
        // test02(); 	编译报错
        // 不能在静态方法里面访问非静态的资源
    }
}
  1. 跨类调用静态资源,建议直接通过类名调用
class Test{
    public static void main(String[] args) {
        //类名进行静态成员变量的调用
        System.out.println(StaticDemo1.num);
        //类名调用静态的成员方法
        StaticDemo1.test01();
        StaticDemo1.test03();
    }
}

2. 静态资源在内存中的表现

// 例子:
public class Cat {
    public String name;
    public String color;
    public static int age;

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                '}';
    }
}

// 测试类
class TestCat {
    public static void main(String[] args) {
        Cat cat = new Cat();
        Cat cat2 = new Cat();

        cat.name = "Hello";
        cat.color = "white";
        cat.age = 2;

        cat2.name = "World";
        cat2.color = "white";

        System.out.println(cat2.name + "\t" + cat2.age);
    }
}

在这里插入图片描述

3. 静态代码块和静态常量的使用

3.1. 静态代码块

静态代码块在类加载时执行,并且只会执行一次

**静态代码块实现格式:**
static {
    // 代码
}
// 例子:
public class StaticDemo02 {
    public static int num=10;

    static {
        num=900;
        System.out.println("静态资源执行了,并且只会执行一次");
    }

    public StaticDemo02(){
        System.out.println("无参构造函数执行了");
    }
}

class TestStaticDemo{
    public static void main(String[] args) {
        StaticDemo02 staticDemo02 = new StaticDemo02();
        // 静态资源执行了,并且只会执行一次
        // 无参构造函数执行了
        StaticDemo02 staticDemo021 = new StaticDemo02();
        // 无参构造函数执行了
    }
}

3.2. 静态常量

若我们数据不允许被外界修改,并且想要共享给所有对象使用,可以使用静态常量

**静态常量的定义:**
public static final 数据类型 变量名称 = 值
// 例子:
public class StaticDemo2 {
    public static final int NUM = 100; // 定义静态常量
 }

静态导包:优势是我们在使用静态方法或者静态变量的时候,直接通过名称就可以调用

**静态导包的格式:**
import static 包名.类名.方法名称 或者
import static 包名.类名.*
// 例子:
public class A {

    public static int age = 100;

    public static void show1(){
        System.out.println("这是静态方法show1");
    }

    public static void show2(){
        System.out.println("这是静态方法show2");
    }
}

// 测试类
package com.doit.demo1;
// 静态导入
//import static com.doit.demo1.A.show1;
//import static com.doit.demo1.A.show2;
import static com.doit.demo1.A.*; // * 代表A类里面的所有静态资源

public class TestA {
    public static void main(String[] args) {
        // 静态导入之后,就可以直接通过静态的方法名称或者变量名称进行调用
        show1();
        show2();
        System.out.println(age);
    }
}

二、内部类

内部类简单来说就是,在一个类的内部嵌套另一个类

1. 内部类的基本使用

1.1. 定义格式

**定义格式:**
public class 外部类的类名{
    class 内部类名{
        ...
    }
}
// 例子:内部类的定义
public class OutClass {
    public String name;
    public int id;

    // 内部类
    class InnerClass {
        public String deptName;
        public String location;
        private double salary;

        public void inner() {
            // 内部类可以直接使用外部类资源
            out();
            // 外部类的私有成员也可以直接使用
            System.out.println(salary);
            System.out.println("这是内部类方法");
        }
    }

    public void out() {
        // 外部类不能直接访问内部类资源,但是可以间接访问
        InnerClass innerClass = new InnerClass();
        System.out.println(innerClass.deptName);

        System.out.println("这是外部类方法");
    }
}

1.2. 内部类的调用

**创建内部类对象:**
外部类类名.内部类类名 变量名= new 外部类类名().new 内部类类名();
// 例子:内部类的创建
class TestInner {
    public static void main(String[] args) {
        OutClass outClass = new OutClass();
        outClass.name = "Exc";
        outClass.id = 0010;
        outClass.out();

        // 创建内部类对象
        // OutClass.InnerClass innerClass = new OutClass().new InnerClass();
        OutClass.InnerClass innerClass = outClass.new InnerClass();
        innerClass.deptName = "JSB";
        innerClass.location = "SH";
        innerClass.inner();
    }
}

总结:

  1. 内部类可以直接使用外部类资源,包括外部类的私有资源也可以
  2. 外部类不能直接访问内部类的资源,只能通过间接方法来调用。例如在方法中创建内部类对象

2. 匿名内部类

相对普通内部类来说,匿名内部类会更加的常见。匿名内部类依旧是一个类,同时也是一个对象,只是没有名字。
我们一般用匿名内部类对父类的方法进行重写或对接口里的方法进行实现。
例子:

// 例子:创建父类(接口同理)
abstract class StaticClass {
    public abstract void show();
}
// 测试类
public class AnonymousInnerClass {
    public static void main(String[] args) {
        System.out.println("*************写法1*************");
        // 匿名内部类其实是将子类的实现与子类对象的创建结合起来了
        // 匿名内部类使用了多态的思想,用了里氏替换原则
        // 匿名内部类不只能重写抽象类
        StaticClass staticClass = new StaticClass() {
            @Override
            public void show() {
                System.out.println("抽象方法被匿名内部类实现了");
            }
        };

        staticClass.show();

        System.out.println("*************写法2*************");
        new StaticClass(){
            @Override
            public void show() {
                System.out.println("抽象方法被匿名内部类实现了");
            }
        }.show();

        System.out.println("************匿名内部类作为参数************");
        showWork(new StaticClass() {
            @Override
            public void show() {
                System.out.println("匿名内部类作为参数实现类showWork方法");
            }
        });
    }

    public static void showWork(StaticClass staticClass){
        staticClass.show();
    }
}

三、“万物之父”Object类

Object类是所有类的超级父类,每个类都将Object类作为超类

1. Object类的常用方法

1.1. toString方法

toString方法:将对象以字符串形式返回

// Object中的toString方法
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
  • getClass.getName():返回对象所属类的全限定名(完整的包名 + 类名)
  • hashCode():用int数据来表示该对象的内存地址
  • toHexString():将hahCode的值转换成16进制的数据
// 例子:
public class Cat {
    public Object name;
    public String color;
    public static int age;
}

// 测试类
class TestCat {
    public static void main(String[] args) {
        Cat cat = new Cat();
        
        System.out.println(cat.toString());     // com.rsdtm.day09.Cat@74a14482
    }
}

想要修改输出格式,可以重写toString方法

public class Cat {
    public Object name;
    public String color;
    public static int age;

    @Override
    public String toString() {
        return "name: " + this.name;
    }
}

class TestCat {
    public static void main(String[] args) {
        Cat cat = new Cat();

        cat.name = "Hello";

        System.out.println(cat.toString());     // name: Hello
    }
}

1.2. equals方法

equals方法:用来比较两个对象是否是同一个对象

// Object类中的equals方法
public boolean equals(Object obj) {
        return (this == obj);
    }
  • Object object: 外界传入的一个对象
  • this: 当前的对象
  • this == obj: 比较当前对象和被传入的对象是否是同一个对象
// 例子:
public class Cat {
    public Object name;
    public String color;
    public static int age;

    @Override
    public String toString() {
        return "name: " + this.name;
    }
}

// 测试类
class TestCat {
    public static void main(String[] args) {
        Cat cat = new Cat();
        Cat cat2 = new Cat();

        cat.name = "Hello";
        cat.color = "white";
        cat.age = 2;

        cat2.name = "Hello";
        cat2.color = "white";

        System.out.println(cat.equals(cat2));	// false
    }
}

假设我们认为name值相同就是一个对象,我们可以改写equals方法

public class Cat {
    public Object name;
    public String color;
    public static int age;

    @Override
    public String toString() {
        return "name: " + this.name;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Cat) {
            Cat c = (Cat) obj;
            return this.name.equals(c.name);
        }
        return false;
    }
}

// 测试类
class TestCat {
    public static void main(String[] args) {
        Cat cat = new Cat();
        Cat cat2 = new Cat();

        cat.name = "Hello";

        cat2.name = "Hello";

        System.out.println(cat.equals(cat2));	// true
    }
}

四、String类

String类位于java.lang包下,用于描述文本

1. 字符串的特点

  1. 字符串的值在创建之后的不能被更改。
  • 如需更改,会创建当前字符串的副本,在副本的基础上进行更改,而不会修改其本身
// 例子:
public class StringDemo1 {
    public static void main(String[] args) {
        String username = "Hello";
        // 经过拼接之后返回的值并不是username本身,而是在内存中重新创建一个了字符串对象来接收helloworld
        username += "World"; 
        System.out.println(username);
    }
}
  1. 直接创建的字符串,其值是可以被共享的。
  • 这种方法创建的字符串会存放在字符串常量池中,调用时会查找常量池中,这个字符串是否存在,存在会直接调用
// 例子:
public class StringDemo1 {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1 == s2); // true
    }
}
  1. 字符串的底层是使用字符数组来存储
// 例子:
public class StringDemo1 {
    public static void main(String[] args) {
        // 定义一个字符数组
        char[] arr = {'a','b','c'};
        // 创建字符串对象的时候,将字符数组传递进去
        String str = new String(arr);
        System.out.println(str);
    }
}

2. 字符串中的构造函数

// 例子:
public class StringTest {
    public static void main(String[] args) {
        System.out.println("构建字符串为空的对象");
        String str01 = new String();
        System.out.println(str01);  // 
        System.out.println("根据指定内容构建字符串对象");
        String str02 = new String("Hello");
        System.out.println(str02);  // Hello
        System.out.println("用字符数组来构建对象");
        char[] chars = {'a', 'b', 'c', 'd', 'e', 'f'};
        String str03 = new String(chars);
        System.out.println(str03);  // abcdef
        System.out.println("根据字符数组的指定区间来构建对象");
        String str04 = new String(chars, 0, 4);
        System.out.println(str04);  // abcd
        System.out.println("根据字符的编码值来构建数组");
        int[] ints = {65, 66, 67, 68, 69, 70};
        String str05 = new String(ints, 0, 4);
        System.out.println(str05);  // ABCD
        System.out.println("根据byte数组构建字符串");
        byte[] bytes = {99, 100, 101, 102, 103, 104, 105};
        String str06 = new String(bytes);
        System.out.println(str06);  // cdefghi
    }
}

3. 字符串的常用方法

3.1. 判断的方法

  1. boolean equals(Object anObject):比较两个字符串的内容是否相等
  2. boolean equalsIgnoreCase(String anotherString):大小写不敏感,比较字符串中的内容
// 例子:
public class StringTestCompare {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = "HELLO";

        System.out.println("equals:");
        System.out.println(str1.equals(str2));  // true
        System.out.println(str1.equals(str3));  // false
        System.out.println("equalsIgnoreCase:");
        System.out.println(str1.equalsIgnoreCase(str2));    // true 
        System.out.println(str1.equalsIgnoreCase(str3));    // true
	}
}
  1. regionMatches(int toffset, String other, int ooffset,
    int len)方法:用于检测两个字符串在一个区域内是否相等
  • ignoreCase – 如果为 true,则比较字符时忽略大小写
  • toffset – 此字符串中子区域的起始偏移量
  • other – 字符串参数
  • ooffset – 字符串参数中子区域的起始偏移量
  • len – 要比较的字符数
// 例子:
public class StringTestCompare {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = "HELLO";

        System.out.println("regionMatches:");
        System.out.println(str1.regionMatches(0, str2, 0, 2));  // true
    }
}
  1. startsWith方法:判断字符串的内容是否以指定的内容开始
  2. endsWith方法:判断字符串的内容是否以指定的内容结束
// 例子:
public class StringTestCompare {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = "HELLO";

        System.out.println("startsWith:");
        System.out.println(str1.startsWith("s"));   // false
        System.out.println("endsWith:");
        System.out.println(str2.endsWith("o"));  //true
    }
}
  1. contains(CharSequence s):判断字符串是否包含指定的内容
// 例子:
public class StringTestCompare {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = "HELLO";

        System.out.println("contains:");
        System.out.println(str1.contains("ll"));    // true
        System.out.println(str1.contains("java"));  // false
    }
}

3.2. 获取的方法

  1. length():获取字符串的长度
// 例子:
public class StringDemo4 {
    public static void main(String[] args) {
        String message = "hello,hadoop";
        System.out.println("字符串的长度是:" + message.length());
    }
}
  1. charAt(int index):返回指定下标的字符
// 例子:
public class StringDemo4 {
    public static void main(String[] args) {
        String message = "hello,hadoop";
        System.out.println("字符串的长度是:" + message.length());
        char c = message.charAt(1);
        System.out.println("指定下标的字符是:" + c);
    }
}
  1. concat(String str):进行字符串的拼接
// 例子:
public class StringDemo4 {
    public static void main(String[] args) {
        //字符串的拼接
        String str1 = message.concat(",hive");
        // + 也是字符串的拼接
        String str2 = message + ",spark";
        System.out.println(str1);
        System.out.println(str2);
    }
}
  1. indexOf(String str):返回指定字符第一次出现的下标。如果不存在,就返回-1
  2. lastIndexOf(String str):返回指定字符最后一次出现的下标。如果不存在,就返回-1
// 例子:
public class StringDemo4 {
    public static void main(String[] args) {
        String str3 = "hello,spark";
        //返回指定字符第一次出现的下标。如果不存在,就返回-1
        System.out.println(str3.indexOf("l"));
        //返回指定字符最后一次出现的下标
        System.out.println(str3.lastIndexOf("l"));
    }
}
  1. subString(int start,int end):截取字符串
// 例子:
public class StringDemo4 {
    public static void main(String[] args) {
        String str3 = "hello,spark";
        //传递一个参数: 从索引值为6开始截取,一直截取到字符串的末尾处
        String newStr = str3.substring(6);
        System.out.println("截取之后的字符串是:" + newStr); // spark
        //截取区间是[6,9)的字符串
        String newStr1 = str3.substring(6,9);
        System.out.println("截取之后的字符串是:" + newStr1); // spa
    }
}
  1. getBytes(String):根据指定的字符串,获取字节数组
// 例子:
public class StringDemo4 {
    public static void main(String[] args) {
        String str4 = "abc";
        // 根据字符串获取指定的字节数组
        byte[] bytes = str4.getBytes();
        for(byte b : bytes){
            System.out.print(b + "  "); // 97 98 99
        }
    }
}
  1. trim():去除空格,返回一个新的字符串
// 例子:
public class StringDemo4 {
    public static void main(String[] args) {
        String str5 = "    abc       ";
        System.out.println(str5);
        //去除字符串前后空格,返回一个新的字符串
        System.out.println(str5.trim());
    }
}

3.3. 转换的方法

  1. char[] toCharArray():将字符串转换成字符数组
public class StringDemo4 {
    public static void main(String[] args) {
        String str8 = "hello";
        char[] chars = str8.toCharArray();
        for(char c1 : chars){
            System.out.println(c1);
        }
    }
}
  1. split(String reg):按照指定的规则切割字符串
// 例子:
public class StringDemo4 {
    public static void main(String[] args) {
        String str6 = "a-b-c-d-e-f-g-h-i";
        String[] split = str6.split("-");
        for(String str : split){
            System.out.println(str);
        }

    }
}
  1. replace(String oldValue,String newValue):将全部的指定内容替换成新内容
public class StringDemo4 {
    public static void main(String[] args) {
        String str9 = "abc";
        String replace_str = str9.replace("bc", "mn");
        System.out.println("替换之后的字符串:" + replace_str);
    }
}
  1. toLowerCase():转小写
  2. toUpperCase():转大写
public class StringDemo4 {
    public static void main(String[] args) {
        System.out.println("abcd".toUpperCase()); 
        System.out.println("ABCD".toLowerCase());
    }
}
  1. valueOf():将指定的内容转换成字符串
public class StringDemo4 {
    public static void main(String[] args) {
        String str_num = String.valueOf(100); // 将int类型的数字转换成字符串
        System.out.println(str_num);
        String str_bool = String.valueOf(true);// 将boolean值转换成字符串
        System.out.println(str_bool);
        String str_char = String.valueOf('a');// 将字符转换成字符串
        System.out.println(str_char);

        String str_obj = String.valueOf(new Fish("金鱼"));
        System.out.println(str_obj);

    }
}

4. StringBuilder

String修改字符串的时候并不会修改字符串本身,而是会在内存中创建一个当前字符串的副本,修改副本。如果我们需要频繁的修改某个字符串,内存中就会产生大量的字符串对象,对内存来说是一种浪费。
这个时候我们可以使用StringBuilder,与String不同,StringBuilder修改的是字符串本身,这样我们对某一个字符串进行频繁地修改就不会使内存中产生大量的字符串对象。

StringBuilder和String的差别

  • StringBuilder修改内容修改的是其本身
  • String修改内容不会修改其本身

4.1. 构造方法

  1. StringBuilder(String str):根据字符串的内容构建一个StringBuilder对象
@Test
    public void stringBuilderTest() {
        System.out.println("*******StringBuilder构造方法*******");
        StringBuilder stringBuilder = new StringBuilder("Hello");
        System.out.println(stringBuilder);  // Hello
    }

4.2. 常用方法

  1. append(String str):在字符串本身的基础上进行内容的追加
@Test
    public void stringBuilderAppend() {
        System.out.println("*******StringBuilder内容的追加*******");
        StringBuilder stringBuilder = new StringBuilder("Hello");
        StringBuilder stringBuilder1 = stringBuilder.append("World");
        System.out.println(stringBuilder == stringBuilder1);    // true
    }
  1. delete(int start,int end):根据指定区间删除字符串内容
  2. deleteCharAt(int index):根据指定位置删除字符串内容
@Test
    public void stringBuilderDelete() {
        System.out.println("*******StringBuilder删除指定区间字符*******");
        StringBuilder stringBuilder01 = new StringBuilder("Hello,World");
        System.out.println(stringBuilder01.delete(6, 9));     // Hello,ld
        System.out.println("*******StringBuilder删除指定位置字符*******");
        StringBuilder stringBuilder02 = new StringBuilder("Hello,World");
        System.out.println(stringBuilder02.deleteCharAt(5));      // HelloWorld
    }
  1. replace(int start, int end, String str):字符串内容替换
@Test
    public void stringBuilderReplace() {
        System.out.println("*******StringBuilder内容的替换*******");
        StringBuilder stringBuilder = new StringBuilder("Hello,World");
        System.out.println(stringBuilder.replace(6, 11, "Java"));   // Hello,Java
    }
  1. insert(int offset, String str):在指定索引值位置上插入新的字符串内容
@Test
    public void stringBuilderInsert() {
        System.out.println("*******StringBuilder指定索引值位置插入新字符串*******");
        StringBuilder stringBuilder = new StringBuilder("Hello");
        System.out.println(stringBuilder.insert(5, "World"));   // HelloWorld
    }
  1. reverse():字符串翻转
@Test
    public void stringBuilderReverse() {
        System.out.println("*******StringBuilder字符串翻转*******");
        StringBuilder stringBuilder = new StringBuilder("Hello");
        System.out.println(stringBuilder.reverse());    // olleH
    }
  1. toString():将StringBuilder对象转换成String对象
@Test
    public void stringBuilderToString() {
        System.out.println("*******StringBuilder对象转换成String对象*******");
        StringBuilder stringBuilder = new StringBuilder("Hello");
        String str = stringBuilder.toString();
        System.out.println(str);    // Hello
    }

4.3. StringBuilder和StringBuffer的区别

以下是一些StringBuffer的常用方法,从用法上来说,两者的区别不大。

StringBuffer常用方法

  • append():将指定的字符串追加到此字符序列
  • insert():将指定的字符串插入此序列的指定点
  • delete():删除此序列的子字符串中的字符
  • deleteCharAt():删除指定位置的字符
  • reverse():将此字符序列用其反转形式取代
  • toString():返回此序列中数据的字符串表示形式

不过我们可以进到两个类的内部去观察他们的方法:

/**StringBuilder*/
@Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
/**StringBuffer*/
@Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

会发现相比于StringBuilder,StringBuffer会多一个关键字synchronized
synchronized就是锁,他可以保证同一时间只会有一个线程执行某个对象的synchronized中的内容,如果其他线程也执行到同一对象的synchronized就会阻塞等待。
从中我们可以得出StringBuilder和StringBuffer的区别:

  1. 线程安全性
    • StringBuffer是线程安全的,它的大多数公共方法都是通过synchronized关键字同步的。这意味着多个线程可以安全地同时使用单个StringBuffer实例而不会发生数据不一致的问题
    • StringBuilder 是非线程安全的,它不提供方法级别的同步(方法上没有synchronized关键字),它在单线程环境下运行时比 StringBuffer 更快,因为它避免了线程同步带来的性能开销
  2. 性能
    • StringBuffer 由于其线程安全的特性,需要进行同步操作,这会导致在高并发场景下性能下降
    • StringBuilder 由于不需要同步,所以在大多数情况下都比 StringBuffer 快,特别是在单线程环境中进行大量字符串操作时

即StringBuffer更安全,而StringBuilder在大多数情况下都比 StringBuffer快。

这就需要我们根据情况来灵活的选择StringBuilder和StringBuffer。
StringBuilder更适合在单线程环境中使用,或者在确信字符串操作只会在一个线程中执行时使用。由于其性能优势,它通常是首选,除非你需要线程安全性。
StringBuffer应该在需要多线程安全的字符串操作时使用,例如,在多个线程需要共享和修改同一个字符串序列的场景中。

五、其他实用类

1. Date类

专门用来描述时间的类,被封装在java.util内。

1.1. 构造函数

@Test
    public void test02() {
        // 获取当前日期
        Date date = new Date();
        System.out.println(date);   // Mon Jul 01 20:00:31 CST 2024
        // 将毫秒值转换成日期
        Date date1 = new Date(171981712);
        System.out.println(date1);      // Sat Jan 03 07:46:21 CST 1970
    }

1.2. 常用方法

  1. getTime():将指定时间转换为毫秒值
    @Test
    public void test02() {
        // 获取当前日期
        Date date = new Date();
        // 将日期转换成毫秒值
        long time = date.getTime();
        System.out.println(time);   // 1719835231780
    }
  1. 年月日等获取的方法
    @Test
    public void test03() {
        Date date = new Date();
        // 获取当前的年份
        int year = date.getYear() + 1900;   // getYear()方法返回的年份是相对于1900年的差值
        System.out.println(year);   // 2024
        // 获取当前月份
        int month = date.getMonth() + 1;    // 返回值是一个介于0到11之间的整数,其中0代表一月,1代表二月,以此类推
        System.out.println(month);  // 7
        // 获取当前小时
        int hours = date.getHours();
        System.out.println(hours);  // 18
        // 获取当前分钟
        int minutes = date.getMinutes();
        System.out.println(minutes);    // 12
        // 获取当前秒
        int seconds = date.getSeconds();
        System.out.println(seconds);    // 10
        // 获取一个星期的第几天
        int day = date.getDay();
        System.out.println(day);    // 1
    }
  1. setTime(Long time):根据毫秒值来设置时间
@Test
    public void test05(){
        // 设置时间
        Date date1 = new Date();
        date1.setTime(2519817450744L);
        System.out.println(date1);
    }
  1. before(Date date)和after(Date date):判断两个时间的先后
@Test
    public void test04(){
        Date date = new Date();
        Date date1 = new Date(23456789102356L);

        System.out.println(date);   // Mon Jul 01 20:22:23 CST 2024
        System.out.println(date1);  // Sat Apr 26 22:45:02 CST 2713

        // 比较两个时间的先后
        System.out.println(date.before(date1)); // true
        System.out.println(date.after(date1));  // false
    }

2. SimpleDateFormat类

主要是用来格式化日期的一个类。SimpleDateFormat继承了Format这个抽象类。被封装在java.text包下。

2.1. 构造函数

SimpleDateFormat(String pattern):根据指定的规则创建SimpleDateFormat对象

标识含义
y
M月份
d天数
H小时
m分钟
s
@Test
    public void test(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
    }

2.2. 常用方法

  1. format(Date date):根据指定的日期进行时间的格式化处理
@Test
    public void test(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        String format = simpleDateFormat.format(new Date());    // 2024-07-01  16:33:41
        System.out.println(format);
    }
  1. parse(String time):将指定格式的日期字符串转换成Date对象
@Test
    public void test02() throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
        String format = simpleDateFormat.format(new Date());
        // parse进行日期转换,要求我们提供的日期格式和SimpleDateFormat指定的格式是一样的,否则会抛出ParseException
        Date parse = simpleDateFormat.parse(format);
        System.out.println(parse);  // Mon Jul 01 20:37:00 CST 2024
    }

3. Calendar类

日历类,通过日历对象提供了更多操作时间的方法,被封装在java.util包下。
由于Calendar是抽象类,因此我们并不能直接创建Calendar对象,只能通过专门的方法来调取。

3.1. 获取当前日历对象

getInstance() 获取当前时间的日历对象

@Test
    public void test03(){
        Calendar instance = Calendar.getInstance();
        System.out.println(instance);	// 太长了就不写了
    }

3.2. 常用方法

日历对象描述日期各个部分的静态成员:

字段值含义
YEAR
MONTH月份
DAY_OF_MONTH / DAY一个月中的第几天
HOUR小时(12小时制)
HOUR_OF_DAY小时(24小时制)
MINUTE分钟
SECOND
DAY_OF_WEEK描述一个星期的第几天
DAY_OF_YEAR一年中的第几天
  1. get方法:获取Calendar对象中指定的时间部分
@Test
    public void test() {
        Calendar instance = Calendar.getInstance();

        int year = instance.get(Calendar.YEAR);
        System.out.println(year);   // 2024

        int month = instance.get(Calendar.MONTH) + 1;
        System.out.println(month);  // 7

        int day = instance.get(Calendar.DAY_OF_MONTH);
        System.out.println(day);    // 1

        int hour_12 = instance.get(Calendar.HOUR);
        System.out.println(hour_12);    // 6

        int hour_24 = instance.get(Calendar.HOUR_OF_DAY);
        System.out.println(hour_24);    // 18

        int min = instance.get(Calendar.MINUTE);
        System.out.println(min);    // 51

        int sec = instance.get(Calendar.SECOND);
        System.out.println(sec);    // 30

        int day_of_week = instance.get(Calendar.DAY_OF_WEEK);
        System.out.println(day_of_week);    // 2

        int day_of_year = instance.get(Calendar.DAY_OF_YEAR);
        System.out.println(day_of_year);    // 183
    }
  1. set():设置时间
  2. add():对时间进行加减
  3. getTime():将Calendar对象转换成Date对象
@Test
    public void test04(){
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.YEAR, 2025);
        Date time01 = instance.getTime();
        String format01 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time01);
        System.out.println(format01);   // 2025-07-01 21:02:32

        instance.set(2024, 2, -1);  // 在指定月份上加/减几天
        Date time02 = instance.getTime();
        String format02 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time02);
        System.out.println(format02);   // 2024-02-28 21:02:32

        instance.set(2024, 2, 0);   // 指定月份的上一个月的最后一天
        Date time03 = instance.getTime();
        String format03 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time03);
        System.out.println(format03);   // 2024-02-29 21:02:32

        instance.add(Calendar.YEAR, 2);     // 指定时间部分上加减时间
        Date time04 = instance.getTime();
        String format04 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time04);
        System.out.println(format04);   // 2026-02-28 21:02:32
    }

补充

IDEA的使用快捷键:

  1. 按住Ctrl,点击类名,可以跳转到该类
  2. Alt+7可以看到当前类的所有字段、属性、方法、是否继承等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值