1、内部类
- 概念:在一个类的内部再定义一个完整的类
- 特点:
- 编译之后可生成独立的字节码文件
- 内部类可直接访问外部类的私有成员,而不破坏封装
- 可为外部类提供必要的内部功能组件
1.1、成员内部类
- 在类的内部定义,与实例变量、实例方法同级别的类
- 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象
- 成员内部类不能定义静态成员,但可以定义静态常量
public static void main(String[] args) {
Other other = new Other();
other.new Inner().show();
}
class Other{
//实例变量
private String name="张三";
private int age=20;
//内部类
class Inner{
private String address="北京";
private String phone="110";
private static final int a=10;
//方法
public void show(){
//访问外部类属性
System.out.println(name); //张三
//访问内部类属性
System.out.println(address); //北京
}
}
}
1.2、静态内部类
- 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
public static void main(String[] args) {
Other1.Inner inner = new Other1.Inner();
inner.show();
}
class Other1{
//实例变量
private String name="张三";
private int age=20;
//静态内部类
static class Inner{
private String address="北京";
private String phone="110";
private static int a=10;
//方法
public void show(){
//访问外部类属性
Other1 other1 = new Other1();
System.out.println(other1.name); //张三
//访问内部类属性
System.out.println(address); //北京
//访问静态成员
System.out.println(a); //10
}
}
}
1.3、局部内部类
- 定义在外部类方法中,作用范围和创建对象仅限于当前方法
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰final
public static void main(String[] args) {
Other2 other2 = new Other2();
other2.show();
}
class Other2{
//实例变量
private String name="张三";
private int age=20;
public void show(){
final String address="北京"; //jdk1.8之后final可省略
//局部内部类
class Inner{
//private String address="北京";
private String phone="110";
public void show2(){
System.out.println(name);
System.out.println(address);
}
}
Inner inner = new Inner();
inner.show2();
}
}
1.4、匿名内部类
- 没有类名的局部内部类(一切特征与局部内部类相同)
- 必须继承一个父类或者实现一个接口
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
- 优点:减少代码量
- 缺点:可读性较差
public static void main(String[] args) {
Usb usb=new Usb() {
@Override
public void service() {
System.out.println("匿名内部类");
}
};
usb.service();
}
interface Usb{
public void service();
}
2、Object类
- 超类、基类,所有类的直接或间接父类,位于继承树的最顶层
- 任何类,如果没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承
- Object类中所定义的方法,是所有对象都具备的方法
- Object类型可以存储任何对象
- 作为参数,可接收任何对象
- 作为返回值,可返回任何对象
2.1、getClass()方法
- public final Class<?> getClass(){}
- 返回引用中存储的实际对象类型
- 应用:通常用于判断两个引用中实际存储对象类型是否一致
public static void main(String[] args) {
Student s1=new Student("aaa",20);
Student s2=new Student("bbb",20);
//判断是不是同一类型
Class<? extends Student> s1Class = s1.getClass();
System.out.println(s1Class); //class com.qianfeng.Student
Class<? extends Student> s2Class = s2.getClass();
if (s1Class==s2Class){
System.out.println("同一个类型"); //true
}else {
System.out.println("不是同一类型");
}
}
class Student{
private String name;
private int age;
2.2、hashCode()方法
- public int hashCode(){}
- 返回该对象的哈希码值
- 一般情况下相同对象返回相同哈希码
public static void main(String[] args) {
Student1 s1=new Student1("aaa",20);
Student1 s2=new Student1("bbb",20);
//不同对象哈希码值不同
System.out.println(s1.hashCode()); //460141958
System.out.println(s2.hashCode()); //1163157884
Student1 s3=s1;
System.out.println(s3.hashCode()); //460141958
}
class Student1{
private String name;
private int age;
2.3、toString()方法
- public String toString(){}
- 返回该对象的字符串表示(表现形式)
- 可以根据程序需求覆盖该方法,如:展示对象各个属性值
public static void main(String[] args) {
Student2 s1=new Student2("aaa",20);
Student2 s2=new Student2("bbb",20);
System.out.println(s1.toString()); //Student2{name='aaa', age=20}
System.out.println(s2.toString()); //Student2{name='bbb', age=20}
}
}
class Student2{
private String name;
private int age;
public Student2() {
}
public Student2(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
2.4.1、equals()方法
- public boolean equals(Object obj){}
- 默认实现为(this==obj),比较两个对象地址是否相同
- 可进行覆盖,覆盖后比较两个对象的内容是否相同
public static void main(String[] args) {
Student3 s1=new Student3("aaa",20);
Student3 s2=new Student3("aaa",20);
System.out.println(s1.equals(s2)); //false
}
}
class Student3{
private String name;
private int age;
public Student3() {
}
public Student3(String name, int age) {
this.name = name;
this.age = age;
}
2.4.2、equals()方法覆盖步骤
- 比较两个引用是否指向同一个对象
- 判断obj是否为null
- 判断两个引用指向的实际对象类型是否一致
- 强制类型转换
- 依次比较各个属性值是否相同
public static void main(String[] args) {
Student4 s1=new Student4("aaa",20);
Student4 s2=new Student4("aaa",20);
System.out.println(s1.equals(s2)); //true
}
}
class Student4{
private String name;
private int age;
public Student4() {
}
public Student4(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student4 student4 = (Student4) o;
return age == student4.age && Objects.equals(name, student4.name);
}
2.5、finalize()方法
- 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
- 垃圾对象:没有有效引用指向此对象,为垃圾对象
- 垃圾回收:由GC销毁垃圾对象,释放数据存储空间
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
- 手动回收机制:使用System.gc();通知JVM执行垃圾回收
3、包装类
- 基本数据类型所对应的引用数据类型
- Object可统一所有数据,包装类的默认值是null
3.1、基本数据类型对应的包装类:
3.2、装箱、拆箱
- valueOf():装箱
- intValue():拆箱
public static void main(String[] args) {
/*
JDK1.5之前,手动装箱和拆箱
*/
//类型转换:装箱,基本数据类型转成引用类型
int num1=19;
Integer integer1 = new Integer(num1); //用构造器
Integer integer2 = Integer.valueOf(num1); //用方法
//类型转换:拆箱,引用类型转成基本数据类型
Integer integer3 = new Integer(100);
int num2 = integer3.intValue();
/*
JDK1.5之后,提供自动装箱和拆箱
*/
int age1=30;
//自动装箱
Integer integer4=age1;
//自动拆箱
int age2=integer4;
}
3.3、类型转换
- toString():基本类型转成字符串
- parseXXX():字符串转成基本类型
//1.基本类型转成字符串
int n1=100;
Integer.toString(n1);
System.out.println(n1); //100
//2.字符串转成基本类型
String str="150";
Integer.parseInt(str); //150
3.4、缓冲区
public static void main(String[] args) {
Integer integer1 = new Integer(100);
Integer integer2 = new Integer(100);
System.out.println(integer1==integer2); //false
Integer integer3=Integer.valueOf(100); //自动装箱
Integer integer4=100; //自动装箱
System.out.println(integer3==integer4); //true
Integer integer5=200; //自动装箱
Integer integer6=200; //自动装箱
System.out.println(integer5==integer6); //false
}
- 自动装箱隐藏的valueOf()方法中有缓存的对象范围(-128-127)
- 因此在这个范围内会使用内存缓存的对象,超过之后才会重新创建新的对象!
2.
3.
4、String类
- 字符串是常量 ,创建之后不可改变(不可变性)
- 字符串字面值存储在字符串中(方法区中),可以共享
- 栈(基本数据类型)、堆(对象)、方法区
- String s =“hello”; //产生一个对象,字符串池中存储
- String s = new String(“hello”); //产生两个对象,堆、池各存储一个
4.1、常用方法
- public int length():返回字符串的长度
String s="java是世界上最坑的语言";
System.out.println(s.length()); //13
- public char charAt(int index):根据下标获取字符
System.out.println(s.charAt(3)); //a
- public boolean contains(String str):判断当前字符串中是否包含str
System.out.println(s.contains("java")); //true
- public char[] toCharArray():将字符串转换成数组
System.out.println(Arrays.toString(s.toCharArray())); //[j, a, v, a, 是, 世, 界, 上, 最, 坑,
- public int indexOf(String str):查找str首次出现的下标,存在,则返回该下标;不存在,则返回-1
String s2="java是世界上最坑的语言java";
System.out.println(s2.indexOf("a")); //1
System.out.println(s2.indexOf("牛")); //-1
System.out.println(s2.indexOf("a",4)); //14
- public int lastIndexOf(String str):查找字符串在当前字符串中最后一次出现的下标索引
System.out.println(s2.lastIndexOf("a")); //16
System.out.println(s2.lastIndexOf("牛")); //-1
- public String trim():去掉字符串前后的空格
String s3=" hello world ";
System.out.println(s3.trim()); //hello world
- public String toUpperCase():将小写转成大写
System.out.println(s3.toUpperCase()); // HELLO WORLD
System.out.println(s3.toLowerCase()); // hello world
- public boolean endWith(String str):判断字符串是否以str结尾
String s4="hello.java";
System.out.println(s4.endsWith(".java")); //true
System.out.println(s4.startsWith("hello")); //true
- public String replace(char oldChar,char newChar):将旧字符串替换成新字符串
String s5="java是世界上最坑的语言java";
System.out.println(s5.replace("java","go")); //go是世界上最坑的语言go
- public String[] split(String str):根据str做拆分
String s6="java is the beat programing beat language ";
String[] arr=s6.split("beat");
System.out.println(arr.length); //3
for (String string :arr) {
System.out.print(string+" "); //java is the programing language
}
- equals:比较值是否相等 (equalsIgnoreCase():忽略大小写比较)
String ss1="hello";
String ss2="HELLO";
System.out.println(ss1.equalsIgnoreCase(ss2)); //true
- compareTo():比较大小(在编码表中的顺序大小依次比较,都一样就比较字符串长度)
String ss3="abc";//97
String ss4="xyz";//120
System.out.println(ss3.compareTo(ss4)); //-23
- substring():截取字符串
4.2、案例演示
需求:
- 已知String str=“this is a text”;
-
- 将str中的单词单独获取出来
-
- 将str中的text替换为practice
-
- 在text前面插入一个easy
-
- 将每个单词的首字母改成大写
String str="this is a text";
String[] arr = str.split(" ");
for (String s :arr) {
System.out.print(s+" "); //this is a text
}
System.out.println("/n");
System.out.println(str.replace("text", "practice")); //this is a practice
System.out.println(str.replace("text", "easy text")); //this is a easy text
for (int i = 0; i < arr.length; i++) {
char first = arr[i].charAt(0);
char upperfirst = Character.toUpperCase(first);
String news = upperfirst + arr[i].substring(1);
System.out.print(news+" "); //This Is A Text
}
5、 可变长字符串
- StringBuffer:可变长字符串,JDK1.0提供,运行效率慢,线程安全
- StringBuilder:可变长字符串,JDK5.0提供,运行效率快,线程不安全
//StringBuffer stringBuffer = new StringBuffer();
StringBuilder stringBuffer = new StringBuilder();
//1.append():追加
stringBuffer.append("java");
System.out.println(stringBuffer); //java
//2.insert():添加
stringBuffer.insert(0,"我在最前面");
System.out.println(stringBuffer); //我在最前面java
//3.replace():指定位置替换 [ )
stringBuffer.replace(0,3,"hello");
System.out.println(stringBuffer); //hello前面java
//4.delete:删除 [ )
stringBuffer.delete(0,5);
System.out.println(stringBuffer); //前面java
6、BigDecimal
double d1=1.0;
double d2=0.9;
System.out.println(d1-d2); //0.09999999999999998
double result=(1.4-0.5)/0.9;
System.out.println(result); //0.9999999999999999
很多实际应用中需要精确运算,而double是近似值存储,不符合 要求,需要借助BigDecimal
- 位置:java.math包中
- 作用:精确计算浮点数
- 创建方式:BigDecimal bd=new BigDecimal(“1.0”);
BigDecimal bd1=new BigDecimal("1.0");
BigDecimal bd2=new BigDecimal("0.9");
//减法
BigDecimal r1=bd1.subtract(bd2);
System.out.println(r1); //0.1
//加法
BigDecimal r2 = bd1.add(bd2);
System.out.println(r2); //1.9
//乘法
BigDecimal r3 = bd1.multiply(bd2);
System.out.println(r3); //0.90
//除法
BigDecimal r4 = new BigDecimal("1.4")
.subtract(new BigDecimal("0.5"))
.divide(new BigDecimal("0.9"));
System.out.println(r4); //1
7、SimpleDateFormat
- SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类
- 进行格式化(日期->文本)、解析(文本->日期)
- 常用的时间模式字母:
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd/ HH-mm-ss");
Date date = new Date();
String format = sdf1.format(date);
System.out.println(format); //2022年12月08日11:12:43
String format1 = sdf2.format(date);
System.out.println(format1); //2022/12/08/ 11-14-50
//解析
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy/MM/dd");
Date date1 = sdf3.parse("1990/05/01");
System.out.println(date1); //Tue May 01 00:00:00 CDT 1990
8、System类
- System系统类,主要用于获取系统的属性数据和其他操作,构造方法私有的