Java 常用类

109 阅读10分钟

Java 常用类

内部类、Object类、包装类、String、BigDecimal类、时间类型

内部类

在一个类的内部再定义一个完整的类

成员内部类、静态内部类、局部内部类、匿名内部类

特点:

  • 编译后可生成独立的字节码文件
  • 内部类可直接访问外部类的私有成员,而不破化封装
  • 可为外部类提供必要的内部功能组件

成员内部类

在类的内部定义,与实例属性、实例方法同一级别

创建内部类对象

  • Outer outer = new Outer();+Outer.Inner inner = out.new Inner();
  • Outer.Inner inner = new Outer.new Inner();

特点:

  • 成员内部类可以使用任何访问修饰符修饰
  • 成员内部类可以直接访问外部类属性方法
  • 成员内部类属性和外部类属性同名时,使用外部类类名.this.外部类属性
  • 成员内部类不能包含静态成员,但可以包含静态常量
public class Outer {

    private String name = "Tom";

    public void show() {
        System.out.println(Inner.KEY);
    }

    public class Inner {

        public static final String KEY = "5563";

        private String name = "John";

        public void show() {

            String name = "Rose";
            
            // 就近原则,若没有局部变量则name为「John」
            // 若没有内部成员变量,则name为「Tom」
            System.out.println(name);
            System.out.println(this.name);
            System.out.println(Outer.this.name);


        }
    }
}

静态内部类

不依赖于外部类对象,可直接创建或类名访问,可声明静态成员

创建静态内部类对象

  • Outer.Inner inner = new Outer.Inner();
  • 静态内部类静态方法:Outer.Inner.show();
  • 可直接导包cn.Outer.Inner;
    • 调用:Inner.show()

特点

  • 静态内部类可使用任何访问修饰符修饰
  • 静态内部类不能直接访问外部类的实例属性和方法,可直接访问静态属性和方法
  • 静态内部类可以包含静态成员

局部内部类

定义在外部类的方法中,作用是访问和创建对象,访问权限仅限于当前方法

特点

  • 不能使用任何访问修饰符修饰
    • 如果局部内部类所在的方法是非静态方法,可以直接访问外部类的实例属性和方法
    • 如果局部内部类所在的方法是静态方法,只能访问外部类的静态属性和方法
  • 局部内部类可以访问局部变量,局部变量必须使用final修饰,「JDK8」以后final关键字可以省略(对象的声明周期长于局部变量)。
  • 局部内部类不能声明静态成员,但可以声明静态常量。
public class localityInnerClass {
    private String name = "name1";

    public void show() {

        final String city = "Peking";
        // city = "122";  // 此处 city 不能再次赋值,city 应为「常量」用 final 修饰,可不写 final 但不能再次赋值
        // 讨论到 栈、堆、方法区$常量池 的声明周期
        class Inner3 {
            
            public static final String work = "work";

            private String like = "like1";

            public void show2() {
                System.out.println(like);
                System.out.println(city);
                System.out.println(name);
            }
        }

        Inner3 inner3 = new Inner3();
        inner3.show2();
    }
}

匿名内部类

相当于没有名字的局部内部类,必须继承一个父类或实现一个接口

定义类、实现类、创建对象语法合并,并只能创建一个该类对象

优点

  • 减少代码量

缺点

  • 可读性差

特点

  • 创建匿名内部类可以使用接口、抽象类、普通类必须实现接口或抽象类中抽象方法

  • 匿名内部类不能手动创建构造方法,不能包含静态成员

  • 匿名内部类中一般不包含特有方法,不能直接访问,可以通过方法调用或内部类调用

  • 匿名内部类可以产生字节码文件,类名$序号.class

  • 接口

public interface USB1 {
    void service();
}
  • 测试匿名内部类
public class TestAnonymity {
    public static void main(String[] args) {

        // 局部内部类
        class USB2 implements USB1 {

            @Override
            public void service() {
                System.out.println("鼠标链接...");
            }
        }
        USB2 usb2 = new USB2();
        usb2.service();


        // 匿名内部类
        USB1 usb1 = new USB1() {
            @Override
            public void service() {
                System.out.println("键盘连接,...");
            }
        };
        usb1.service();
        

        // Lambda 表达式 接口中只有一个方法,代码块中只有一条语句
        USB1 usb4 = () -> System.out.println("Mouse use");
        usb4.service();

        // 多条语句用大括号
        USB1 usb3 = () -> {System.out.println("KeyBoard use");
            System.out.println("start");};
        usb3.service();

    }
}

Object 类

超类、基类,所有类的直接或间接父类,位于继承树的最高层

  • 任何类,如没有书写extends显示继承某个类,都默认继承Object类,否则为间接继承
  • Object类中所定义的方法,是所有对象都具备的方法
  • Object类型可以存储任何对象
    • 作为参数,可接受任何对象
    • 作为返回值,可返回任何对象

Object 类中的方法

  1. getClass()方法
  • 返回引用中存储对象实际类型
    • 返回class 全限定名
  • 对象名.getClass().getName()
    • 返回全限定名
  1. hashCode()方法
  • 返回该对象的十进制的哈希码值
  • debug时观察到的地址值为哈希码值的十六进制值
  1. toString()方法
  • 默认返回该对象的全限定名@十六进制哈希码值
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
  • 将其进行重写,返回该对象属性的字符串表示
  1. equals()方法
  • 默认实现为:下面代码,比较两个对象地址值是否相同
public boolean equals(Object obj) {
    return (this == obj);
}
  • 覆盖equals()方法步骤
    • 判断obj是否为null
    • 比较两个引用是否指向同一个对象
    • 判断两个引用指向的实际对象类型是否一致
    • 强制类型转化
    • 依次比较各个属性值是否相同
@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (this == obj) {
        return true;
    }
    if (this.getClass() != obj.getClass()) {
        return false;
    }
    if (obj instanceof Student) {
        Student student = (Student) obj;
        if (this.age == student.age && this.name.equals(student.name)) {
            return true;
        }
    }
    return false;
}
  1. finalize()方法
  • 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
  • 垃圾对象:没有有效引用指向此对象,为垃圾对象
  • 垃圾回收:由GC销毁垃圾对象,释放数据存储空间
  • 自动回收机制JVM的内存耗尽,一次性回收所有垃圾对象
  • 手动回收机制:使用System.gc()通知JVM执行垃圾回收

包装类

基本数据类型所对应的引用数据类型,Object类可同一所有数据,包装类的默认是null

基本数据类型包装类型
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

类型转换

  1. 基本数据类型和为包装类转换(以int和Integer为例)

装箱

Integer n1 = new Integer(20); // JDK9弃用

int n2 = 10;
Integer n3 = Integer.valueOf(n2); // 通过valueOf静态方法将基本数据类型转为包装类

拆箱

Integer n1 = new Integer(20);
int n2 = n1.intValue();

基本数据行与String类型转换

int n1 = Integer.parseInt("20"); 
// 这里要转换为int类型,字符串里面必须是一个整数。
// 要保证类型兼容
// 否则,抛出:NumberFormatException
  1. 包装类的一些其他方法及属性
  • Integer.MAX_VALUE // int最大值
  • Integer.MIN_VALUE // int最小值
  • Integer.toBinaryString(20) // 将数字转为二进制
  • Integer.toHexString(20) // 将数字转为十六进制
  • Integer.toOctalString(20) // 将数字转为八进制
  • Integer.bitCount(20) // 一个数二进制数有多少个1
  1. 自动拆箱、装箱

JDK5.0之后,自动装箱、拆箱。基本数据类型和包装类自动转换

Integer n1 = 30; // 装箱,底层其实还是调用valueOf()

int n2 = n1; // 拆箱,底层调用intValue()

整数缓冲区

为什么要介绍这个呢?这里有个题可以看看

    // 第一组
    Integer i1=new Integer(100);//0x0000A001
    Integer i2=new Integer(100);//0x0000B002
    System.out.println(i1==i2);//==比较地址值  false

    // 第二组
    Integer i3=Integer.valueOf(100);//100
    Integer i4=100;//100
    System.out.println(i3==i4);//true  100==100

    // 第二组
    Integer i5=200;//new Integer(200);
    Integer i6=200;//new Integer(200);
    System.out.println(i5==i6);//  false

第二组为什么是true,和valueOf()底层密不可分,底层中预先创建了256个常用的整数包装类型对象,在实际应用当中,对已创建的对象进行复用。这里就不详细介绍了。

String 类

Java 程序中的所有字符串文本都是此类的实例,字符串字面量是常量,具有不可变性,创建后不可改变。

常用创建方式

String str1 = new String("Java");
String str2 = "Java";

常用方法

  • public char charAt(int index):根据下标获取字符

  • public boolean contains(String str):判断当前字符串是否包含str

  • public char[] toCharArray():将字符串转换成数组

  • public int indexOf(String str):查找str首次出现的下标,存在,则返回该下标;不存在返回-1

  • public int length():返回字符串长度

  • public String trim():去掉字符串前后的空格

  • public String toUpperCase():将小写转换成大写

  • public boolean endsWith(String str):判断字符串是否以str结尾

  • public String replace(char oldChar,char newChar):将旧字符串替换成新字符串

  • public String[] split(String str):根据str做拆分

  • public String subString(int beginIndex,int endIndex):在字符串中截取一个字符串

StringBuffer 和 StringBuilder

可在内存中创建可变的缓冲空间,存储频繁改变的字符串

位于java.lang包下

常用方法

  • append():追加
  • insert():插入
  • replace():替换
  • delete():删除

区别

  • StringBuffer:可变长字符串,JDK1.0提供的,运行效率慢,线程安全
  • StringBuilder:可变长字符串,JDK5.0提供的,运行效率快,线程不安全

BigDecimal 类

精准计算浮点数

位于java.math包下

创建方式

BigDecimal db = new BigDecimal("1.0");

常用方法

  • add(BigDecimal bd):加法运算
  • substract(BigDecimal bd):减法运算
  • multiply(BigDecimal bd):乘法运算
  • divide(BigDecimal bd):除法运算

Math 类

Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。

位于java.lang包下

常用方法

  • static double random():生成[0,1)范围内的随机数
  • static double pow(double a, double b):计算a的b次幂的值
  • static double sqrt(double a):平方根
  • static double cbrt(double a)

Random 类

此类的实例用于生成伪随机数流

  • 位于java.util包下
  • 此类使用 48 位的种子,使用线性同余公式 (linear congruential form) 对其进行了修改所得。
  • long种子确定,则在不同程序中,相同次数产生的随机数是相同的。
Random random = new Random();
random.nextInt(20); // 获取[0,20)返回内的整数

Date 类

Date 表示精确的瞬间,精确到毫秒

Date中大部分方法都已经被calendar类中的方法取代

Date date = new Date(); // date 可以直接打印
// toLocaleString 更方便观察
date.getTime() // 获取当前时间毫秒值

Calendar 类

Calendar 提供了获取或设置各种日历字段的方法

位于java.util包下

Calendar的构造方法为protected修饰,无法直接创建该对象。因此要用Calendar的静态方法getInstance()来获取日历对象。

常用方法

方法名说明
void set(int year, int month, int date, int hourofday, int minute, int second)设置日历的时间
int get(int field)返回给定日历字段的值
void setTime(Date date)将Date转为Calendar
void getTime()将Calendar转为Date
void add(int field, int amount)给某个日历往前推时间,或往后推时间,amount参数是推几天
long getTimeMillis()返回日历的时间毫秒值

SimpleDateFormat 类

SimpleDateFormat 是以与语言环境相关的方式来格式化和解析日期的类

位于java.text包下

格式化:日期 转为 文本 解析: 文本 转为 日期

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 创建对象
Date date = new Date(); // 创建日期对象
String string = simpleDateFormat.format(date); // 格式化
date = simpleDateFormat.parse(string); // 解析

System 类

System 系统类,主要用于获取系统的属性数据和其他操作

位于java.lang包下

常用方法

  • static void arraycopy():将一个数组拷贝到另一个数组,用于数组扩容
  • static void currentTimeMillis():获取当前系统时间的毫秒值,用这个也可使测试一段程序的运行时间
// 在这里我们测试一下之前的 StringBuffer 和 StringBuilder 的运行速率怎么样
long start1 = System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer();
int count1 = 0;
while (count1 < 100000000) {
    stringBuffer.append("a");
    count1++;
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1); // 获得毫秒值

long start2 = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
int count2 = 0;
while (count2 < 100000000) {
    stringBuilder.append("a");
    count2++;
}
long end2 = System.currentTimeMillis();
System.out.println(end2 - start1);
  • static void gc():建议JVM启动垃圾回收器回收垃圾,只是建议
  • static void exit(int status):退出JVM,如果是0则正常退出JVM,如果是非零则异常退出JVM

Runtime 类

每个 Java 程序都有一个 Runtime 实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。

位于java.lang包下

常用方法

方法说明
Process exec()输入notepad可以启动记事本,输入程序入口的绝对路径也可启动程序
void exit(int status)退出虚拟机
void gc()和System系统类中的gc方法相同,只是System也是调用的这个gc()方法
long totalMemory()获取内存总量,获取的应该是KB,除两次1024获得GB
long freeMemory()获取空闲内存量
long maxMemory()虚拟机试图使用的最大内存量