2-Java常用类
内部类
概念:在一个类的内部再定义一个完整的类
特点:编译后可生成独立的字节码文件
内部类可直接访问外部类私有成员,而不破坏封装
package operator;
public class Body {
private String name;
class Header{
public void show(){
System.out.println("name");
}
}
}
可为外部类提供必要的内部功能组件
成员内部类
package operator;
public class Outer {
//实例变量
private String name="张三";
private int age=20;
class Inner{
private String address="北京";
private String phone="123456";
public void show(){
System.out.println("show");
//打印外部类的属性
System.out.println(name);
System.out.println(age);
//打印内部类的属性
System.out.println(address);
System.out.println(phone);
}
}
}
class Test{
public static void main(String[] args) {
Outer.sayHello();
//创建外部类对象
Outer outer=new Outer();
//创建内部类对象
Outer.Inner inner=outer.new Inner();//也能写 new Outer().new Inner()一样
inner.show();
//张三
//20
//北京
//123456
}
}
当外部类和内部类出现同名的属性时,会优先读取内部类的属性
package operator;
public class Outer {
//实例变量
private String name="张三";
private int age=20;
public static void sayHello(){
System.out.println("hello");
}
class Inner{
private String address="北京";
private String phone="123456";
private String name="李四";
public void show(){
System.out.println("show");
//打印外部类的属性
System.out.println(name);
System.out.println(age);
//打印内部类的属性
System.out.println(address);
System.out.println(phone);
}
}
}
class Test{
public static void main(String[] args) {
Outer.sayHello();
//创建外部类对象
Outer outer=new Outer();
//创建内部类对象
Outer.Inner inner=outer.new Inner();//也能写 Outer.Inner inner=new Outer().new Inner()一样
inner.show();
//李四
//20
//北京
//123456
}
}
除非改成才能访问外部类属性System.out.println(Outer.this.name);
成员内部类不能定义静态成员,错误private static String name="李四";
但能定义静态常量
private static final String name="李四";
静态内部类
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
只有内部类可以用静态,外部类不能用静态
package operator;
public class Outer {
private String name="张三";
private int age=20;
//静态内部类,加了static后,级别和外部类一样,可以理解是和外部类是平行的
static class Inner{
private String address="北京";
private String phone="123456";
private static int count=100;
public void show(){
//如何调用外部类的属性
//先创建外部类的对象,再调用外部类的属性
Outer outer = new Outer();
System.out.println(outer.name);
System.out.println(outer.age);
//调用静态内部类的属性
System.out.println(phone);
System.out.println(address);
//调用静态内部类的静态属性
System.out.println(Inner.count);
}
}
}
class Test{
public static void main(String[] args) {
//直接创建静态内部类对象
Outer.Inner inner = new Outer.Inner();//不是new Outer().new Inner()
inner.show();
}
}
局部内部类
1、定义在外部类的方法中,作用范围和创建对象范围仅限于当前方法
2、局部内部类访问外部类当有方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final
package operator;
public class Outer {
private String name="张三";
private int age=20;
public void show(){
//定义局部变量
String address="深圳";
//定义局部内部类,类名不能加任何访问修饰符
class Inner {
// 定义局部内部类的属性
private String phone="1234567890";
private String email="6023@qq.com";
public void show2() {
// 访问外部类的属性
System.out.println(Outer.this.name);
System.out.println(Outer.this.age);
// 访问局部内部类的属性
System.out.println(this.phone);
System.out.println(this.email);
//访问局部变量,jdk1.8以后可以不用声明为final,但是其实系统已经加上了final关键字了,意味着后期不能修改了
//局部内部类访问局部变量时,会将其转化成final类型-常量,实际上adrress已经被替换成深圳
System.out.println(address);
}
}
//创建局部内部类的对象
Inner inner = new Inner();
inner.show2();
}
}
class Test{
public static void main(String[] args) {
Outer outer = new Outer();
outer.show();
//如果上面不加Inner inner = new Inner();inner.show2();outer.show();这一步是不会有任何输出结果 ,
//加了后,会输出:张三、20、1234567890、6023@qq.com
}
}
匿名内部类
没有类名的局部内部类
必须继承一个父类或实现一个接口(简化代码)
定义类,实现类,创建对象语法合并,只能创建一个该类的对象,简化代码,但是可读性差
package operator;
public class TestUsb {
public static void main(String[] args) {
//创建接口类型的变量
/*Usb usb = new Mouse();
usb.service();*/
//局部内部类,现在在main方法中
class Fan implements Usb {
@Override
public void service() {
System.out.println("风扇连接成功");
}
}
//使用局部内部类创建对象
Usb usb = new Fan();
usb.service();
//使用匿名内部类优化(相当于创建了一个局部内部类),可以接口,父类,上面那种方法也可以,只是使用一次就不用,可以用这个方法简化代码
Usb usb2 = new Usb() {
@Override
public void service() {
System.out.println("风扇连接成功哈哈");
}
};
usb2.service();
//风扇连接成功
//风扇连接成功哈哈
}
}
Object类常用方法
超类,基类,所有类都直接或间接父类
Object类所定义的方法,是所有对象都具备的方法
getClass()方法-返回引用中存储的实际对象类型
package operator;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
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) {
this.age = age;
}
}
package operator;
public class TestStudent {
public static void main(String[] args) {
Student s1 = new Student("aaa", 20);
Student s2 = new Student("bbb", 21);
//判断s1和s2是不是同一个类型
Class class1 = s1.getClass();
Class class2 = s2.getClass();
if (class1 == class2) {
System.out.println("s1和s2是同一个类型");
} else {
System.out.println("s1和s2不是同一个类型");
}
}
}
hashCode()方法
public int hashCode){}
返回对象的哈希码值
沿用上面的代码
//hashCode()方法
System.out.println("s1的hashCode()方法返回值:" + s1.hashCode());//990368553
System.out.println("s2的hashCode()方法返回值:" + s2.hashCode());//1828972342
toString()方法
public String toString(){}
返回该对象的字符串表示
但是一般会在子类重写toString方法,同时生成中也有默认toString
package operator;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
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) {
this.age = age;
}
public String toString() {
return name + " :" + age;
}
}
package operator;
public class TestStudent {
public static void main(String[] args) {
Student s1 = new Student("aaa", 20);
Student s2 = new Student("bbb", 21);
//判断s1和s2是不是同一个类型
Class class1 = s1.getClass();
Class class2 = s2.getClass();
if (class1 == class2) {
System.out.println("s1和s2是同一个类型");
} else {
System.out.println("s1和s2不是同一个类型");
}
//hashCode()方法
System.out.println("s1的hashCode()方法返回值:" + s1.hashCode());//990368553
System.out.println("s2的hashCode()方法返回值:" + s2.hashCode());//1828972342
//toString()方法
//没在Student类中重写前
System.out.println( s1.toString());//类的全路径名@哈希码,哈希码的十进制表示就是hashCode()方法的返回值
System.out.println( s2.toString());//operator.Student@6d03e736
//重写了toString()方法
System.out.println( s1.toString());//Student{name='aaa', age=20}
System.out.println( s2.toString());//Student{name='bbb', age=21}
}
}
equals()方法
pubic boolean equals(Object obj){}
默认实现为(this==obj),比较两个对象地址是否相同
可进行覆盖,重写方法
重写equals方法,使两个对象变成一个对象
package operator;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
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) {
this.age = age;
}
public String toString() {
return name + " :" + age;
}
@Override
public boolean equals(Object obj) {
//判断两个对象是否相等
if (this == obj)
return true;
//判断obj是否null
if (obj == null)
return false;
//判断是否是同一个类型
//if (this.getClass()!= obj.getClass())
if (obj instanceof Student) {
//强制类型转换
Student student = (Student) obj;
if (this.name.equals(student.name) && this.age == student.getAge()) {
return true;
}
}
return false;
}
}
finalize()方法
当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
垃圾对象:没有有效引用指向此对象时,就是垃圾对象
垃圾回收:由GC销毁垃圾对象,释放数据空间
自动回收机制,JVM内存耗尽,一次性回收所有垃圾对象
手动回收机制,使用System.gc(),通知JVM执行垃圾回收
package operator;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
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) {
this.age = age;
}
public String toString() {
return name + " :" + age;
}
@Override
protected void finalize() throws Throwable {
System.out.println(this.name+"对象被回收了");
}
}
package operator;
public class TestStudent {
public static void main(String[] args) {
//new Student("aa",20);
// new Student("bb",21);
//new Student("cc",22);
// new Student("dd",23);
//new Student("ee",24);
new Student("aa",20);
new Student("bb",21);
new Student("cc",22);
new Student("dd",23);
new Student("ee",24);
//回收垃圾
System.gc();
System.out.println("回收垃圾");
}
}
不知为什么idea没显示XXX对象被回收了
包装类
基本数据类型所对应的引用数据类型-因为基本数据类型是不带方法和属性的,所以为了让其有方法和属性,JDK设计就将基本数据类型也有对应的引用数据类型
类型转换与装箱、拆箱
装箱-把基本类型变成对象,从栈到堆
拆箱-把对象变成基本类型、从堆到栈
package operator;
public class Demo1 {
public static void main(String[] args) {
int num = 10;
//类型转换,装箱,基本类型转为引用类型
//使用Integer创建对象
Integer integer1 = new Integer(num);//构造方法
Integer integer2 = Integer.valueOf(num);//方法,两个方式
System.out.println("装箱");
System.out.println(integer1);
System.out.println(integer2);
//类型转化,拆箱,引用类型转为基本类型
Integer integer3 = new Integer(100);
int num2 = integer3.intValue();
System.out.println("拆箱");
System.out.println(num2);
//以上是jdk1.5之前的类型转换方式,jdk1.5之后,可以使用自动装箱和拆箱来实现类型转换
int num3 = 10;
//自动装箱
Integer integer4 = num3;
System.out.println("自动装箱");
System.out.println(integer4);
//自动拆箱
int num4 = integer4;
System.out.println("自动拆箱");
System.out.println(num4);
}
}
基本类型和字符串之间的转换
//基本类型转成字符串
```
int n1=100;
//使用+号
String str1=n1+"";
//使用Integer.toString()方法
String str2=Integer.toString(n1);
System.out.println(str1);
System.out.println(str2);
//字符串转成基本类型
String str3="150";
//使用Integer.parseInt()方法
int n2=Integer.parseInt(str3);
System.out.println(n2);
//boolean字符串转成基本类型
String str4="true";
//使用Boolean.parseBoolean()方法
boolean b=Boolean.parseBoolean(str4);
System.out.println(b);
##整数缓冲区
Java预先创建了256个常用的整数包装类型对象(-127~128),用Integer.valueOf时
package operator;
public class Demo1 {
public static void main(String[] args) {
Integer i1 = new Integer(100);
Integer i2 = new Integer(100);
System.out.println(i1 ==i2);// false,new出来的对象不同,所以地址不同,用的是构造器方法
Integer i3 = 100;//实际代码是Integer i3 = Integer.valueOf(100);用的是类方法,是同一个对象指向两个对象引用,但是地址是相同
Integer i4 = 100;
System.out.println(i3 == i4);//true,
Integer i5 = 200;
Integer i6 = 200;
System.out.println(i5 == i6);//false,因为这个整数包装类的范围是-128~127,200超出了这个范围,所以是false
}
}
#String类
字符串是常量,创建之后不可改
字符串字面值存储在字符串池(方法区)中,可以共享。内存有堆、栈、方法区
String s="Hello"产生一个对象,字符串池中存储
String s=new String("Hello");产生两个对象,堆,池各存储一个
package operator;
public class Demo1 {
public static void main(String[] args) {
String name = "John";//john常量存在字符串常量池中
name = "zhangsan";//把mike赋值给name变量,并没有修改数据,而是重新开了新的空间
String name2 = "zhangsan";//同一个对象,name2和name指向同一个字符串常量,地址相同
//演示字符串另一种创建方式
String str=new String("java");//会在堆和字符串常量池各创建一个对象,并最后指向字符串常量,这种方式比较耗费内存
}
}



##常用方法
package operator;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) {
String name = "John";//john常量存在字符串常量池中
name = "zhangsan";//把mike赋值给name变量,并没有修改数据,而是重新开了新的空间
String name2 = "zhangsan";//同一个对象,name2和name指向同一个字符串常量,地址相同
//演示字符串另一种创建方式
String str=new String("java");//会在堆和字符串常量池各创建一个对象,并最后指向字符串常量,这种方式比较耗费内存
//字符串方法的使用
//1,length()方法获取字符串长度
//2,charAt(int index)方法获取指定位置的字符
//3,contains(String str)方法判断字符串是否包含指定字符串
String content = "java是世界上最好的编程语言,java是面向对象编程的语言";
System.out.println(content.length());//输出:15
System.out.println(content.charAt(0));//输出:j
System.out.println(content.contains("编程"));//输出:true
//4,toCharArray()方法将字符串转换为字符数组
//5,indexOf(String str)方法获取指定字符串第一次出现的位置
//6,lastIndexOf(String str)方法获取指定字符串最后一次出现的位置
System.out.println(Arrays.toString(content.toCharArray()));//输出:[j, a, v, a, , 世, 界, 上, 最, 好, 的, 程, 序, 言, 语]
System.out.println(content.indexOf("java"));//输出:0
System.out.println(content.lastIndexOf("java"));//输出:16
//7,trim()方法去除字符串两端的空格
//8,touppercase()方法将字符串全部转换为大写
//8,toLowerCase()方法将字符串全部转换为小写
//9,endsWith(String str)方法判断字符串是否以指定字符串结尾,startsWith(String str)方法判断字符串是否以指定字符串开头
String content2 = " Helloworld ";
System.out.println(content2.trim());//输出:Helloworld
System.out.println(content2.toUpperCase());//输出:HELLOWORLD
System.out.println(content2.toLowerCase());//输出:helloworld
System.out.println(content2.endsWith("world"));//输出:true
//10,replace(char oldChar, char newChar)方法替换字符串中的指定字符
//11,split()方法按照指定字符分割字符串
System.out.println(content.replace("java", "php"));//输出:php是世界上最好的编程语言,php是面向对象编程的语言
String say="hello world";
String[] arr=say.split(" ");
//补充两个方法equals()和compare()比较大小
String str1="hello";
String str2="HELLO";
System.out.println(str1.equals(str2));//false
String str3="abc";//拿a和x比较大小,a是97,x是120,这时候比较位置,如果str3='abc',str4='abcxyz',这个时候就比较长度了,结果是-3
String str4="xyz";
System.out.println(str3.compareTo(str4));//-23
}
}
##可变字符串
package operator;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) {
//StringBuffer和StringBuilder的使用,和String区别,效率比String高(用时快),比String更节省内存
StringBuffer sb = new StringBuffer();//和StringBuilder一样,但效率StringBuilder更高
//append方法可以连续添加字符串
sb.append("Hello");
System.out.println(sb.toString());
sb.append("World");
System.out.println(sb.toString());
//insert方法可以插入字符串
sb.insert(0, "Java");
System.out.println(sb.toString());
//replace方法可以替换字符串
sb.replace(0, 4, "C++");
System.out.println(sb.toString());
//delete方法可以删除字符串
sb.delete(0, 3);
System.out.println(sb.toString());
//Hello
//HelloWorld
//JavaHelloWorld
//C++HelloWorld
//HelloWorld
}
}
#BigDecimal类
double是近似值存储,不在符合要求,有些实际应用需要精确运行,需要借助BigDecimal
位置:java.math包
作用:精确计算浮点数
创建方式:BigDecimal bd =new BigDecimal("1.0");
package operator;
import java.math.BigDecimal;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) {
double d1=1.0;
double d2=0.9;
System.out.println(d1-d2);//0.09999999999999998
//BigDecimal,大的浮点数精确计算
BigDecimal bd1=new BigDecimal("1.0");
BigDecimal bd2=new BigDecimal("0.9");
System.out.println(bd1.subtract(bd2));//0.1
//加法
BigDecimal r2=bd1.add(bd2);
System.out.println(r2);//1.9
//乘法
BigDecimal r3=bd1.multiply(bd2);
System.out.println(r3);//0.9
//除法
BigDecimal r4=bd1.divide(bd2,2,BigDecimal.ROUND_HALF_UP);
System.out.println(r4);//1.11
}
}
#Date类
package operator;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
public class Demo1 {
public static void main(String[] args) {
//创建Date对象
Date date1 = new Date();
System.out.println(date1.toString());
System.out.println(date1.toLocaleString());
//使用方法afetr()获取当前时间的后一天,before()获取当前时间的前一天
//比较 compareTo()
}
}
##Calendar
提供了获取或设置各种日历字段的方法
package operator;
import java.util.Calendar;
public class Demo1 {
public static void main(String[] args) {
//创建Calendar对象,由于构造方法是私有的,所以只能使用Calendar.getInstance()方法获取Calendar对象
Calendar calendar = Calendar.getInstance();
System.out.println("当前时间是: " + calendar.getTime());
//获取时间信息
//获取年
int year = calendar.get(Calendar.YEAR);
System.out.println("年: " + year);
//获取月
}
}
##SimpleDateFormat
进行格式化(日期转到文本)(文本转到日期)
package operator;
import java.util.Calendar;
import java.util.Date;
public class Demo1 {
public static void main(String[] args) {
//创建SimpleDateFormat对象,并设置日期格式为yyyy-MM-dd HH:mm:ss
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("当前时间:" + sdf.format(Calendar.getInstance().getTime()));
//创建Date
Date date = new Date();
//将Date转换为String
String strDate = sdf.format(date);
System.out.println("当前时间:" + strDate);
}
}
##System类
主要是获取系统属性数据和其他操作,构造方法私有的
package operator;
import java.util.Calendar;
import java.util.Date;
public class Demo1 {
public static void main(String[] args) {
//arraycopy:数组的复制
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = new int[8];
System.arraycopy(arr1, 0, arr2, 0, arr1.length);
for (int i = 0; i < arr2.length; i++) {
System.out.print(arr2[i] + " ");// 1 2 3 4 5 0 0 0
}
System.out.println(System.currentTimeMillis());
//System.gc();告诉JVM进行垃圾回收
}
}
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术