内部类:
成员内部类:
public class Outer {
//实例变量
private String name = "张三";
private int age = 20;
//内部类
class Inner{
//private static String country = "中国";报错
//private static final String country = "中国";但可以包括静态常量
private String address="北京";
public String phone = "110";
private String name = "李四";
//方法
public void show(){
//打印外部类的属性,内部类属性和外部类的属性名相同Outer.this
System.out.println(name);//优先访问内部类属性
System.out.println(Outer.this.name);//访问外部类同名属性
System.out.println(age);
//打印内部类中的属性
System.out.println(address);
System.out.println(phone);
}
}
}
public class TestOuter {
public static void main(String[] args) {
//1.创建一个外部类对象
//Outer outer = new Outer();
//2.创建内部类对象
//Outer.Inner inner = outer.new Inner();
//一步到位
Outer.Inner inner = new Outer().new Inner();
inner.show();//李四 张三 20 北京 110
}
}
为了增加可读性,可以明确一下:
public class Outer {
//实例变量
private String name = "张三";
private int age = 20;
//内部类
class Inner{
private String address="北京";
public String phone = "110";
//属性和外部类的属性名相同,Outer.this
private String name = "李四";
//方法
public void show(){
//打印外部类的属性,内部类属性和外部类的属性名相同Outer.this
System.out.println(Outer.this.name);//访问外部类同名属性
System.out.println(Outer.this.age);
//打印内部类中的属性
System.out.println(this.address);
System.out.println(this.phone);
}
}
静态内部类:
只有内部类才能通过static修饰
静态内部类不能直接访问外部类属性,需要先创建外部对象再调用外部类对象的属性
//外部类
public class Outer {
private String name = "xxx";
private int age = 18;
//静态内部类,级别和外部类相同
static class Inner{
private String address = "上海";
private String phone = "111";
//静态成员
private static int count = 1000;
public void show(){
//调用外部类的属性
//1.先创建外部类对象
Outer outer = new Outer();
//2.调用外部类对象的属性
System.out.println(outer.name);
System.out.println(outer.age);
//调用静态内部类的属性和方法
System.out.println(address);
System.out.println(phone);
//调用静态内部类的静态属性
System.out.println(Inner.count);
}
}
}
public class TestOuter {
public static void main(String[] args) {
//直接创建静态内部类对象
Outer.Inner inner = new Outer.Inner();//这里不是new Outer().new Inner() Outer.Inner()表示一种包含关系
//调用方法
inner.show();
}
}
局部内部类:
局部内部类注意不能加任何访问修饰符
局部内部类可以直接访问外部类属性,因为和方法是平级的
如果是静态方法,局部内部类就不能访问外部类属性了,因为静态方法不能访问非静态属性,只能创建对象访问
public class Outer {
private String name = "刘德华";
private int age = 35;
public void show(){//如果是静态方法就不行了,静态方法不能访问非静态属性,只能创建对象访问
//定义局部变量
String address = "深圳";// final String address局部变量执行完方法后会消失,所以要加final
//局部内部类:注意不能加任何访问修饰符
class Inner{
private String phone = "1588888888";
private String email = "liudehua@qq.com";
//private final static int count = 2000;
public void show2(){
//访问外部类的属性
System.out.println(name);
System.out.println(age);
//System.out.println(Outer.this.name);
//System.out.println(Outer.this.age);
//访问内部类的属性
System.out.println(phone);
System.out.println(email);
//System.out.println(this.phone);
//System.out.println(this.email);
//访问局部变量,jdk1.7要求:变量必须是常量final,jdk1.8自动添加final
System.out.println(address);
}
}
//创建局部内部类对象
Inner inner = new Inner();
inner.show2();
}
}
public class TestOuter {
public static void main(String[] args) {
Outer outer = new Outer();
outer.show();//刘德华 35 1588888888 liudehua@qq.com
}
}
匿名内部类:
使用匿名内部类优化,相当于创建了一个局部内部类
//接口
public interface Usb {
//服务
void service();
}
public class Mouse implements Usb{
@Override
public void service(){
System.out.println("连接电脑成功,鼠标开始工作了");
}
}
public class TestUsb {
public static void main(String[] args) {
//创建接口类型地变量
// Usb usb = new Mouse();
// usb.service();
//局部内部类
// class Fan implements Usb{
// @Override
// public void service(){
// System.out.println("连接电脑成功,风扇开始工作了。");
// }
// }
//使用局部内部类创建对象
// Usb usb = new Fan();
// usb.service();
//使用匿名内部类优化,相当于创建了一个局部内部类
Usb usb = new Usb() {
@Override
public void service() {
System.out.println("连接电脑成功,风扇开始工作了。");
}
};
usb.service();
}
}
Object类:
getClass():
返回的是一个class类型
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
}
public class TestStudent {
public static void main(String[] args) {
Student s1 = new Student("aaa",20);
Student s2 = new Student("bbb",22);
//判断s1和s2是不是同一个类型 Class类后面再讲
Class class1 = s1.getClass();
Class class2 = s2.getClass();
System.out.println(class1);//class chapter1.Student
System.out.println(class2);//class chapter1.Student
if(class1==class2){
System.out.println("s1和s2属于同一个类型");
}else{
System.out.println("s1和s2不属于同一个类型");
}
}
}
hashCode():
public class TestStudent {
public static void main(String[] args) {
Student s1 = new Student("aaa",20);
Student s2 = new Student("bbb",22);
//hashCode方法
System.out.println(s1.hashCode());//460141958
System.out.println(s2.hashCode());//1163157884
Student s3 = s1;
System.out.println(s3.hashCode());//460141958
}
}
toString():
重写前:
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
}
public class TestStudent {
public static void main(String[] args) {
Student s1 = new Student("aaa",20);
Student s2 = new Student("bbb",22);
//toString方法
System.out.println(s1.toString());//chapter1.Student@1b6d3586
System.out.println(s2.toString());//chapter1.Student@4554617c
}
}
重写后:
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
//重写
@Override
public String toString(){
return name + ":" + age;
}
}
public class TestStudent {
public static void main(String[] args) {
Student s1 = new Student("aaa",20);
Student s2 = new Student("bbb",22);
//toString方法
System.out.println(s1.toString());//aaa:20
System.out.println(s2.toString());//bbb:22
}
}
equals():
源码:
public boolean equals(Object obj) {
return (this == obj);
}
重写前:
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj){
return true;
}
}
public class TestStudent {
public static void main(String[] args) {
Student s1 = new Student("aaa",20);
Student s2 = new Student("bbb",22);
Student s3 = s1;
//equals方法,判断两个对象是否相等
System.out.println(s1.equals(s2));//false
System.out.println(s1.equals(s3));//true
Student s4 = new Student("小明",17);
Student s5 = new Student("小明",17);
System.out.println(s4.equals(s5));//false
}
}
重写后:满足我们自己的需求
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
//重写
@Override
public boolean equals(Object obj){
//1.判断两个对象是否是用一个引用
if(this == obj){
return true;
}
//2.判断obj是否null
if(obj==null){
return false;
}
//3.判断两个引用指向的实际对象类型是否一致
// if(this.getClass()==obj.getClass()){
// return true;
// }
//instanceof判断对象是否是某种类型
if(obj instanceof Student){
//4.强势类型转换
Student s = (Student) obj;//obj可能是相关父类,所以需要强制转换一下
//5.比较熟悉
if(this.name.equals(s.getName())&&this.age==s.getAge()){
//这里name是String类型,String类里重写了equals方法
return true;
}
}
return true;
}
}
public class TestStudent {
public static void main(String[] args) {
//equals方法,判断两个对象是否相等
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s3));//true
Student s4 = new Student("小明",17);
Student s5 = new Student("小明",17);
System.out.println(s4.equals(s5));//true
}
}
String类里重写了equals方法
finalize():
源码:没有任何的代码不用调用,需要重写
protected void finalize() throws Throwable { }
重写:
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
@Override
protected void finalize() throws Throwable {
System.out.println(this.name+"对象被回收");
}
}
public class TestStudent2 {
public static void main(String[] args) {
Student s1 = new Student("aaa",20);
Student s2 = new Student("bbb",20);
Student s3 = new Student("ccc",20);
Student s4 = new Student("ddd",20);
Student s5 = new Student("eee",20);
//回收垃圾
System.gc();
System.out.println("回收垃圾");//回收垃圾 这5个对象的finalize方法没有执行,说明没有进行回收,说明这5个对象不是垃圾对象
}
}
把对象变成垃圾对象:
public class TestStudent2 {
public static void main(String[] args) {
// Student s1 = new Student("aaa",20);
// Student s2 = new Student("bbb",20);
// Student s3 = new Student("ccc",20);
// Student s4 = new Student("ddd",20);
// Student s5 = new Student("eee",20);
new Student("aaa",20);
new Student("bbb",20);
new Student("ccc",20);
new Student("ddd",20);
new Student("eee",20);
//回收垃圾
System.gc();
System.out.println("回收垃圾");
//回收垃圾
//eee对象被回收
//ddd对象被回收
//ccc对象被回收
//bbb对象被回收
//aaa对象被回收
}
}
包装类:
八种基本类型没有任何的属性和方法
基本数据类型存放在栈里面,引用类型数据存放在堆里面
将栈数据转化为堆数据叫装箱,将堆数据转换为栈数据叫拆封
包装类的作用就是将栈里面的基本数据类型与堆里面的对象相互装箱拆箱
以装箱拆箱int基本类型为例:查看包装类Integer类拥有的其中两个用于装箱和拆箱的方法
jdk1.5之前的装箱和拆箱过程
public class Demo01 {
public static void main(String[] args) {
//jdk1.5之前的装箱和拆箱
//类型转换:装箱,基本类型转成引用类型的过程
//基本类型
int num1 = 18;//基本数据类型,没有任何属性和方法
//使用Integer类创建对象
Integer integer1 = new Integer(num1);
Integer integer2 = Integer.valueOf(num1);
System.out.println("装箱");
System.out.println(integer1);//18(引用类型)
System.out.println(integer2);//18(引用类型)
//类型转换:拆箱,引用类型转成基本类型
Integer integer3 = new Integer(100);
int num2 = integer3.intValue();
System.out.println("拆箱");
System.out.println(num2);//100(基本数据类型)
}
}
jdk1.5之后的装箱和拆箱过程
public class Demo01 {
public static void main(String[] args) {
//jdk1.5之后的装箱和拆箱
int age = 30;
//自动装箱
Integer integer4 = age;
System.out.println("自动装箱");
System.out.println(integer4);//30(引用类型)
//自动拆箱
int age2 = integer4;
System.out.println("自动拆箱");
System.out.println(age2);//30(基本数据类型)
}
}
基本类型和字符串转换:
public class Demo02 {
public static void main(String[] args) {
//1.基本类型转成字符串
int n1 = 15;
//1.1使用+号
String s1 = n1 + "";
//1.2使用Integer中的toString()方法
String s2 = Integer.toString(n1);
String s3 = Integer.toString(n1,16);//重载方法 16进制
System.out.println(s1);//15
System.out.println(s2);//15
System.out.println(s3);//f
//2.字符串转成基本类型
String str = "150";
//使用Integer.parseXXX();
int n2 = Integer.parseInt(str);
System.out.println(n2);
//boolean字符串形式转成基本类型:“true”--->true,非“true”--->false
String str2 = "true";
boolean b1 = Boolean.parseBoolean(str2);
System.out.println(b1);
}
}
Integer缓冲区:
public class Demo03 {
public static void main(String[] args) {
//面试题
Integer integer1 = new Integer(100);
Integer integer2 = new Integer(100);
System.out.println(integer1==integer2);//false
Integer integer3 = 100;//自动装箱Integer.valueOf
Integer integer4 = 100;
//Integer integer3 = Integer.valueOf(100);
//Integer integer4 = Integer.valueOf(100);
System.out.println(integer3==integer4);//true
Integer integer5 = 200;
Integer integer6 = 200;
//Integer integer5 = Integer.valueOf(200);
//Integer integer6 = Integer.valueOf(200);
System.out.println(integer5==integer6);//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);//如果不在这个-128-127直接new一个
}
private static class IntegerCache {
static final int low = -128;//-128
static final int high;//127
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
integer1==integer2比较的是地址不一样false
integer3==interger4 valueOf预存的数据在栈中分配了两个相同的地址,所以为true,其实就相当于Integer integer4=integer3
integer5==interger6 200不在-128-127的范围内,地址不一样false
String类:
public class Demo04 {
public static void main(String[] args) {
String name = "hello";//"hello"常量存储在字符串池中
name = "zhangsan";//"张三"赋值给name常量,给字符串赋值时,并没有修改数据,而是重新开辟空间
String name2 = "zhangsan";
//演示字符串的另一种创建方式
//String str = "java是最好的语言";
String str = new String("java");
String str2 = new String("java");
System.out.println(str == str2);//比较地址
System.out.println(str.equals(str2));//String重写了equals方法比较值
}
}
public class Demo05 {
public static void main(String[] args) {
//字符串方法的使用
//1.length();返回字符串的长度
//2.charAt(int index);返回某个位置的字符
//3.contains(String str);是否包含某个字符串
System.out.println("---------字符串方法的使用1----------");
String content= "java是世界上最好的java编程语言,java真香";
System.out.println(content.length());//26
System.out.println(content.charAt(content.length()-1));//香
System.out.println(content.contains("java"));//true
System.out.println(content.contains("php"));//false
System.out.println("---------字符串方法的使用2-----------");
//字符串方法的使用
//4.toCharArray();返回字符串对应的数组
//5.indexOf();返回子字符串首次出现的位置
//6.lastIndexOf();返回字符串最后一次出现的位置
System.out.println(Arrays.toString(content.toCharArray()));//[j, a, v, a, 是, 世, 界, 上, 最, 好, 的, j, a, v, a, 编, 程, 语, 言, ,, j, a, v, a, 真, 香]
System.out.println(content.indexOf("java"));//0
System.out.println(content.indexOf("java",4));//11 从第几个开始算
System.out.println(content.lastIndexOf("java"));
System.out.println("---------字符串方法的使用3-----------");
//7.trim();去掉字符串前后的空格
//8.toUpperCase();把小写转成大写,toLowerCase();把大写转成小写
//9.endsWith(str);判断是否已str结尾,startWith(str);判断是否已str开头
String content2 = " helloworld ";
System.out.println(content2.trim());//helloworld
System.out.println(content2.toUpperCase());// HELLOWORLD
System.out.println(content2.toLowerCase());// helloworld
String filename = "hello.java";
System.out.println(filename.endsWith(".java"));//true
System.out.println(filename.startsWith("hello"));//true
System.out.println("---------字符串方法的使用4-----------");
//10.replace(char old,char new);用新的字符或字符串替换旧的字符或字符串
//11.split();对字符串进行拆分
System.out.println(content.replace("java","php"));//php是世界上最好的php编程语言,php真香
String say = "java is the best programing language,,,,java xiang";
String[] arr = say.split("[ ,]+");//空格逗号分割,+无视分隔符的数量
for (String string : arr){
System.out.println(string);
}
System.out.println("---------字符串方法的使用4-----------");
//补充两个方法equals比较内容,compareTo()比较大小
String s1 = "hello";
String s2 = "HELLO";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true 无视字母大小
String s3 = "abc";//97
String s4 = "xyz";//120
System.out.println(s3.compareTo(s4));//-23
String s5 = "abc";
String s6 = "abcxyz";
System.out.println(s5.compareTo(s6));//比较长度了
}
}
public class Demo06 {
public static void main(String[] args) {
String str = "this is a text";
//1.将str中的单词单独获取出来
String [] str1 = str.split(" ");
for(String arg:str1){
System.out.println(arg);
}
//2.将str中的text替换为practice
String str2 = str.replace("text","practice");
System.out.println(str2);
//3.在text前面插入一个easy
String str3 = str.replace("text","easy text");
//4.将每个单词的首字母换成大写
for(int i = 0;i < str1.length;i++){
char first = str1[i].charAt(0);
//把第一个字符转成大写
char upperfirst = Character.toUpperCase(first);
String news = upperfirst + str1[i].substring(1);//从第二个字符开始截取
System.out.println(news);
}
}
}
public class Demo07 {
public static void main(String[] args) {
//StringBuilder sb = new StringBuilder();
StringBuffer sb = new StringBuffer();
//1.append
sb.append("java世界第一");
System.out.println(sb.toString());
sb.append("java真香");
System.out.println(sb.toString());
sb.append("java不错");
System.out.println(sb.toString());
//2.insert();添加
sb.insert(0,"我在最前面");
System.out.println(sb.toString());
//3.replace();
sb.replace(0,5,"hello");
System.out.println(sb.toString());
//4.delete;删除
sb.delete(0,5);
System.out.println(sb.toString());
}
}
效率体现:
public class Demo08 {
public static void main(String[] args) {
//开始时间
// 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));94533
long start = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for(int i = 0;i<99999;i++){
sb.append(i);
}
System.out.println(sb);
long end = System.currentTimeMillis();
System.out.println("用时:"+(end-start));//63
}
}
BigDecimal类:
public class Demo09 {
public static void main(String[] args) {
//浮点型采用的是一种近似值的存储方式,结果会有误差,但误差很小
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
//BigDecimal,大的浮点数精确计算
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
BigDecimal r5 = new BigDecimal(20).divide(new BigDecimal("3"),2,BigDecimal.ROUND_HALF_UP);//保留两位小数四舍五入
System.out.println(r5);//6.67
}
}
Data类:
public class Demo10 {
public static void main(String[] args) {
//1.创建Date对象
//今天
Date date1 = new Date();
System.out.println(date1.toString());//Fri Nov 19 10:34:41 CST 2021
System.out.println(date1.toLocaleString());//2021-11-19 10:34:41
//昨天
Date date2 = new Date(date1.getTime()-(60*60*24*1000));
System.out.println(date2.toLocaleString());//2021-11-18 10:34:41
//2.方法 after before
boolean b1 = date1.after(date2);
System.out.println(b1);//true
boolean b2 = date1.before(date2);
System.out.println(b2);//false
//3.比较compareTo()
int d = date1.compareTo(date2);
System.out.println(d);//1
int s = date2.compareTo(date1);
System.out.println(s);//-1
//4.比较是否相等equals()
boolean b3 = date1.equals(date2);
System.out.println(b3);//false
}
}
Calendar类:
public class Demo11 {
public static void main(String[] args) {
//1.创建Calendar对象
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTime().toLocaleString());//2021-11-19 11:16:48
//2.获取时间信息
//获取年
int year = calendar.get(Calendar.YEAR);
//月从0-11
int month = calendar.get(Calendar.MONTH);
//日
int day = calendar.get(Calendar.DAY_OF_MONTH);
//小时
int hour = calendar.get(Calendar.HOUR_OF_DAY);
//分钟
int minute = calendar.get(Calendar.MINUTE);
//秒
int second = calendar.get(Calendar.SECOND);
System.out.println(year+"年"+(month+1)+"月"+day+"日"+hour+":"+minute+":"+second);//2021年11月19日11:16:48
//3.修改时间
Calendar calendar2 = Calendar.getInstance();
calendar2.set(Calendar.DAY_OF_MONTH,5);
System.out.println(calendar2.getTime().toLocaleString());//2021-11-5 11:16:48
//4.add方法修改时间
calendar2.add(Calendar.HOUR,1);
System.out.println(calendar2.getTime().toLocaleString());//2021-11-5 12:16:48
//5.补充方法
calendar2.add(Calendar.MONTH,1);
int max = calendar2.getActualMaximum(Calendar.DAY_OF_MONTH);
int min = calendar2.getActualMinimum(Calendar.DAY_OF_MONTH);
System.out.println(max);//31
System.out.println(min);//1
}
SimpleDateFormate类:
public class Demo12 {
public static void main(String[] args) {
//1.创建SimpleDateFormat对象y年m月
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");//把时间使用这个格式来输出
//2.创建Date
Date date = new Date();
//格式化date(把日期转成字符串)
String str = sdf.format(date);
System.out.println(str);//2021/11/20
//解析(把字符串转成日期)
try {
Date date2 = sdf.parse("1990/05/01");
System.out.println(date2);//Tue May 01 00:00:00 CDT 1990
}catch (ParseException e){
System.out.println("异常");
}
}
}
System类:
public class Demo13 {
public static void main(String[] args){
//1.arraycopy:数组的复制
//src:源数组
//srcPos:从哪个位置开始复制
//dest:目标数组
//destPos:从目标数组哪个位置开始放
//length:复制的长度
int[] arr={20,18,15,8,35,26,45,90};
int[] dest = new int[8];
System.arraycopy(arr,0,dest,0,arr.length);
for(int i = 0;i<dest.length;i++){
System.out.println(dest[i]);
}
//2.获取毫秒数
System.out.println(System.currentTimeMillis());//1637378377669
long start = System.currentTimeMillis();
for (int i = -99999999;i<99999999;i++){
for(int j = -99999999;j<99999999;j++){
int result = i+j;
}
}
long end = System.currentTimeMillis();
System.out.println("用时:"+(end-start));//8
//3.回收垃圾
new Student("aaa",19);
new Student("bbb",19);
new Student("ccc",19);
System.gc();//告诉垃圾回收器回收
//4.退出JVM
System.exit(0);
System.out.println("程序结束");
}
}