内部类
-
内部类:在一个类的内部再定义一个完整的类
package com.category.category_1; //身体 public class Body { private String name; //头部 class Header{//内部类也会生成class文件,此处:Body$Header.class public void show(){//内部类可以访问外部类的私有成员 System.out.println(name); } } }
-
特点:内部类可直接访问外部类的私有成员,而不破坏封装
-
分为:成员内部类、静态内部类、局部内部类、匿名内部类
-
成员内部类
-
当外部类、内部类存在重名属性时,优先访问内部类属性
-
成员内部类不能定义静态成员
-
package com.category.category_1; public class Outer { //实例变量 private String name = "张三"; private int age = 20; //内部类 class Inner{ private String address = "北京"; private String phone = "110"; //当内部类属性和外部类属性名相同,如果想通过内部类访问外部类,则需要Outer.this.name private String name = "李四"; //成员内部类不能定义静态成员,但是可以有静态常量 private static final String country = "中国"; //方法 public void show(){ //打印外部类的属性 System.out.println(Outer.this.name); System.out.println(age); //打印内部类中的属性 System.out.println(address); System.out.println(phone); } } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.category.category_1; public class OuterTest { public static void main(String[] args) { /* //1.创建外部类对象 Outer outer = new Outer(); //创建内部类对象 Outer.Inner inner = outer.new Inner(); */ //一步到位 Outer.Inner inner = new Outer().new Inner(); inner.show(); Outer outer = new Outer(); System.out.println(outer.getName()); } }
-
-
静态内部类
-
只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
-
只有内部类才能用static修饰
-
package com.category.category_2; public class Outer { private String name = "xxx"; private int age = 18; //静态内部类:级别和外部类相同!!! static class Inner{ private String address = "上海"; private String phone = "123"; //静态成员 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(this.address); System.out.println(this.phone); //调用静态内部类的静态属性 System.out.println(Inner.count); } } }
package com.category.category_2; public class OuterTest { public static void main(String[] args) { //直接创建静态内部类对象 Outer.Inner inner = new Outer.Inner(); //调用方法 inner.show(); } }
-
-
局部内部类
-
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
-
局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,所以变量必须定义为final
-
局部内部类限制了类的使用方法:当前方法
-
package com.category.category_3; import java.lang.ref.SoftReference; public class Outer { private String name = "刘德华"; private int age = 35; public void show(){ //定义局部变量 final表示常量,之后不能对此值进行修改 String address = "深圳"; //局部内部类:注意不能加任何访问修饰符 class Inner{ private String phone = "11111111111"; private String email = "asdjfkajsdh"; // private final static int count = 10; 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); //访问局部变量,自动添加final System.out.println(address); } } //创建局部内部类对象 Inner inner = new Inner(); inner.show2(); } }
package com.category.category_3; public class OuterTest { public static void main(String[] args) { Outer outer = new Outer(); outer.show(); } }
-
-
匿名内部类
-
没有类名的局部内部类
-
必须继承一个父类或实现一个接口
-
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
package com.category.category_4; //接口 public interface Usb { //服务 void service(); }
package com.category.category_4; public class Mouse implements Usb { @Override public void service() { System.out.println("连接电脑成功,鼠标开始工作了"); } }
package com.category.category_4; public class UsbTest { 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类
-
超类、基类,是所有类的直接或间接的父类
-
未写extends的任何类默认继承Object
-
Object类型可以存储任何对象
-
作为参数可以接收任何对象
-
作为返回值可以返回任何对象
getclass()方法
-
返回当前对象的类的类型
-
通常用于判断两个引用中实际存储对象的类型是否一致
hashCode()方法
-
哈希值根据对象的地址或字符串或数字使用hash算法计算出的int类型的数值
-
一般情况下,相同对象返回相同的哈希码
toString()方法
-
返回该对象的字符串表示(表现形式)
-
可以根据程序需求重写该方法
equals()方法
-
默认实现为比较两个对象是否相等(this == obj)
-
可进行重写为比较两个对象的内容分是否相同
-
equals方法的重写步骤
-
比较两个引用类型是否指向同一个对象
-
判断obj是否为null
-
判断两个引用指向的实际对象类型是否一致
-
强制类型转换
-
依次比较各个属性值是否相同
-
finalize()方法
-
垃圾对象:没有有效引用指向此对象时,为垃圾对象
-
垃圾回收:由gc销毁垃圾对象,释放数据存储空间
-
自动回收机制:Jvm的内存耗尽,一次性回收所有垃圾对象
-
手动回收机制:使用System.gc()通知Jvm执行垃圾回收
package com.category.category_5; public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return name+":"+ 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; //5.比较属性 if (this.name.equals(s.getName())&&this.age==s.getAge()){ return true; } } return false; } @Override protected void finalize() throws Throwable { System.out.println(this.name+"对象被回收了"); } }
package com.category.category_5; import java.util.Arrays; public class TestStudent { public static void main(String[] args) { System.out.println("===========getClass()==========="); Student s1 = new Student("aaa",111); Student s2 = new Student("bbb",222); //判断s1和s2是不是同一个类型 Class class1 = s1.getClass(); Class class2 = s2.getClass(); if (class1 == class2){ System.out.println("s1和s2属于同一个类型"); }else{ System.out.println("s1和s2不属于同一个类型"); } System.out.println("==========hashCode()============"); //hashCode方法 System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); Student s3 = s1; System.out.println(s3.hashCode()); System.out.println("===========toString()==========="); //toString方法 System.out.println(s1.toString()); System.out.println(s2.toString()); System.out.println("===========toString()打印数组==========="); int[] a = {1,2,3,3,4,5}; System.out.println(Arrays.toString(a)); System.out.println("===========equals()==========="); //equals方法,判断两个对象是否相等 System.out.println(s1.equals(s2)); Student s4 = new Student("qqq", 12); Student s5 = new Student("qqq", 12); System.out.println(s4.equals(s5)); } }
package com.category.category_5; public class TestStudent2 { public static void main(String[] args) { // Student s1 = new Student("aaa", 111); // Student s2 = new Student("bbb", 111); // Student s3 = new Student("ccc", 111); // Student s4 = new Student("ddd", 111); // Student s5 = new Student("eee", 111); new Student("aaa", 111); new Student("bbb", 111); new Student("ccc", 111); new Student("ddd", 111); new Student("eee", 111); //回收垃圾 System.gc(); System.out.println("回收垃圾"); } }
包装类
-
指基本数据类型所对应的引用数据类型
-
Object可统一所有数据包装类默认值null
类型转换与装箱、拆箱
-
需保证类型兼容,否则抛出异常:NumberFormatException
整数缓冲区
-
Java创建了256个常用整数包装类型对象
-
在实际应用中,对创建的对象进行复用
-
package com.category.category_6; public class Demo01 { public static void main(String[] args) { int num = 10; //类型转换:装箱,基本类型转换为引用类型 //基本类型 int num1 = 18; //使用Integer类创建对象 Integer integer1 = new Integer(num1); Integer integer2 = Integer.valueOf(num1); 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后提供自动装箱和拆箱 int age = 30; //自动装箱 System.out.println("自动装箱"); Integer integer4 = age; System.out.println(integer4); //自动拆箱 System.out.println("自动拆箱"); int age2 = integer4; System.out.println(age2); System.out.println("================基本类型和字符串之间的转换==========================="); //基本类型和字符串之间的转换 //1.基本类型转换成字符串 int n1 = 15; //1.使用+ String s1 = n1 + ""; //2.使用Integer中的toString方法 String s2 = Integer.toString(n1,16);//将n1以16进制输出 System.out.println(s1); System.out.println(s2); //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); } }
package com.category.category_6; public class Demo02 { 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 integer3 = Integer.valueOf(100); Integer integer4 = 100; System.out.println(integer3 == integer4);//Integer integer4 = Integer.valueOf(100); Integer integer5 = 127;//自动装箱Integer integer5 = Integer.valueOf(127); Integer integer6 = 127;//Integer integer6 = Integer.valueOf(127); System.out.println(integer5 == integer6); //valueOf()范围-128---127,超过范围会溢出,会直接new一个对象,所以地址不同 } }
String类
-
字符串是常量,创建之后不可改变
-
字符串字面值存储在字符串中池中,可以共享
-
String s = "xxx" ;产生一个对象,存储在字符串池中
-
String s = new String("xxx"); 产生两个对象,堆、池中各存在一个
String常用方法
package com.category.category_6; import java.util.Arrays; import java.util.Locale; public class Demo03 { public static void main(String[] args) { //String的不可变性 String name = "Hello";//"Hello"常量存储在字符串池中 name = "张三";//"张三"赋值给name变量,给字符串赋值时,并没有修改之前的值"Hello",而是重新开辟了一个空间 String name2 = "张三"; System.out.println(name == name2);//当另一个值也赋值"张三"时,在方法区中已经存在,所以两个变量公用一个地址 System.out.println(name.equals(name2)); Integer integer1 = new Integer(10); Integer integer2 = new Integer(10); System.out.println(integer1.equals(integer2)); //字符串的另一种创建方式 String str = new String("Java是最好的编译语言");//在方法区中和堆中都创建了对象 String str1 = new String("Java是最好的编译语言"); System.out.println(str == str1);//false,new创建了不同的对象 System.out.println(str.equals(str1));//进行字符串的比较使用equals!!!!!! System.out.println("===============字符串方法的使用======================="); //字符串方法的使用 String content = "Java是最好的编译语言"; String content2 = " Java是最好的编译语言 "; //1.length();返回字符串的长度 System.out.println(content.length()); //2.charAt(int index);返回某个位置的字符 System.out.println(content.charAt(0)); System.out.println(content.charAt(content.length()-1)); //3.contains(String str);判断是否包含某个字符串 System.out.println(content.contains("Java")); //4.toCharArray();将字符串转换成数组 System.out.println(Arrays.toString(content.toCharArray())); //5.indexOf(String str);查找str首次出现的位置下标,存在则返回该下标,不存在则返回-1 System.out.println(content.indexOf("的")); System.out.println(content.indexOf("java",4));//查找从下标为4开始str首次出现的位置下标,存在则返回该下标,不存在则返回-1 //6.lastIndexOf(String str);查找字符串在当前字符串中最后一次出现的位置下标 System.out.println(content.lastIndexOf("a")); System.out.println(content.lastIndexOf("a",2)); //7.trim();去掉字符串前后的空格 System.out.println(Arrays.toString((content2.trim()).toCharArray())); //8.toUpperCase();将小写转换为大写;toLowerCase();将小写转换为大写 System.out.println(content.toUpperCase()); System.out.println(content.toLowerCase()); //9.endWith(String str);判断字符串是否以str结尾;startWith(String str);判断字符串是否以str开头 System.out.println(content.endsWith("言")); System.out.println(content2.endsWith("言")); System.out.println(content.startsWith("J")); System.out.println(content2.startsWith("J")); //10.replace(char oldChar,char newChar);将旧字符串替换成新字符串 System.out.println(content2.replace(" ","12")); //11.split(String str);根据str做拆分 String say = "Java is the best programing language"; String say1 = "Java is the best programing language,Java xiang"; String say2 = "Java is the best programing language,Java xiang"; String[] arr = say.split(" "); System.out.println(Arrays.toString(arr)); for (String s : arr) { System.out.println(s); } String[] arr1 = say1.split("[ ,]"); System.out.println(Arrays.toString(arr1)); for (String s : arr1) { System.out.println(s); } String[] arr2 = say2.split("[ ,]+"); System.out.println(Arrays.toString(arr2)); for (String s : arr2) { System.out.println(s); } //12.equals();比较字符串是否相等 String s1 = "hello"; String s2 = "HELLO"; System.out.println(s1.equals(s2));//直接比较 System.out.println(s1.equalsIgnoreCase(s2));//忽略大小写的比较 //13.compareTo();比较大小(比较首个字符在编码表中的位置,全等的字符串输出0) //当长度相同时:如果首个字符相同则比较下一个字符,最后输出字符编码的差值 String s3 = "abc";//97 String s4 = "xyz";//120 System.out.println(s3.compareTo(s4));//-23(s3 - s4) //当长度不同时:比较字符串的长度,输出长度之差 String s5 = "abc"; String s6 = "abcxyz"; System.out.println(s5.compareTo(s6));//s5 - s6 } }
package com.category.category_6; /* * 已知String str = "this is a test" * 将str中的单词单独获取出来 * 将str中的test替换为practice * 在test前加一个easy * 将每个单词的首字母大写 * */ public class Demo04 { public static void main(String[] args) { String str = "this is a test"; //将str中的单词单独获取出来 String[] arr = str.split(" "); for (String s : arr) { System.out.println(s); } //将str中的test替换为practice System.out.println(str.replace("test","practice")); //在test前加一个easy System.out.println(str.replace("test","easy test")); //将每个单词的首字母大写 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.println(news); } } }
package com.category.category_6; /* * StringBuffer和StringBuilder的使用 * 和String的区别: * (1)效率比String高 * (2)比String节省内存 * */ public class Demo05 { public static void main(String[] args) { // StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder(); //1.append();追加 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()); //5.清空 sb.delete(0,sb.length()); System.out.println(sb.length()); } }
package com.category.category_6; /* * 验证StringBuilder效率高于String * * */ public class Demo06 { 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);*/ StringBuilder sb = new StringBuilder(); for (int i = 0; i < 99999; i++) { sb.append(i); } System.out.println(sb.toString()); long end = System.currentTimeMillis(); System.out.println("用时:"+(end-start)); } }
BigDecimal
-
进行高精度运算时,由于Double是近似值存储,不符合要求,所以需要使用BigDecimal
-
精确计算浮点数
package com.category.category_6; import java.math.BigDecimal; public class Demo07 { public static void main(String[] args) { double d1 = 1.0; double d2 = 0.9; System.out.println(d1 - d2); double result = (1.4 - 0.5)/0.9; System.out.println(result);//double是近似值存储 //BigDecimal:用于大的浮点数的精确计算 BigDecimal bd1 = new BigDecimal("1.0"); BigDecimal bd2 = new BigDecimal("0.9"); //减法运算 BigDecimal r1 = bd1.subtract(bd2); System.out.println(r1); //加法运算 BigDecimal r2 = bd1.add(bd2); System.out.println(r2); //乘法运算 BigDecimal r3 = bd1.multiply(bd2); System.out.println(r3); //除法 BigDecimal r4 = new BigDecimal("1.4") .subtract(new BigDecimal("0.5")) .divide(new BigDecimal("0.9")); System.out.println(r4); //除不尽时使用BigDecimal的重写方法 BigDecimal r5 = new BigDecimal("10") .divide(new BigDecimal("3"),2,BigDecimal.ROUND_HALF_UP);//BigDecimal.ROUND_HALF_UP表示四舍五入 System.out.println(r5); } }
Date
-
Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法已经被Calender类中的方法所取代
-
时间单位
-
1秒 = 1000毫秒
-
1毫秒 = 1000微秒
-
1微秒 = 1000纳秒
-
package com.category.category_7; import java.util.Date; public class Demo01 { public static void main(String[] args) { //1.创建Date对象 //今天 Date date1 = new Date(); System.out.println(date1.toString()); System.out.println(date1.toLocaleString()); //昨天 Date date2 = new Date(date1.getTime()-2*60*60*24*1000); System.out.println(date2.toString()); System.out.println(date2.toLocaleString()); //2.使用方法after、before boolean b1 = date1.after(date2);//date1是否在date2之后? System.out.println(b1); boolean b2 = date1.before(date2);//date1是否在date2之前? System.out.println(b2); //3.比较compareTo int d = date1.compareTo(date2); int d1 = date2.compareTo(date1); System.out.println(d); System.out.println(d1); //4.equals方法比较时间是否相等 boolean b3 = date1.equals(date2); System.out.println(b3); } }
Calender方法
package com.category.category_7; import java.util.Calendar; public class Demo02 { public static void main(String[] args) { //创建一个Calender对象 Calendar calendar = Calendar.getInstance(); System.out.println(calendar.getTime().toLocaleString()); System.out.println(calendar.getTimeInMillis()); //2.获取时间信息 //获取年 int year = calendar.get(Calendar.YEAR); //月返回时从0开始所以输出+1 int month = calendar.get(Calendar.MONTH); //日 int day = calendar.get(Calendar.DAY_OF_MONTH);//或者使用Calendar.DATE //小时 int hour = calendar.get(Calendar.HOUR_OF_DAY);//24小时,若使用HOUR为12小时制 //分钟 int minute = calendar.get(Calendar.MINUTE); //秒 int second = calendar.get(Calendar.SECOND); //修改时间 Calendar calendar2 = Calendar.getInstance(); calendar2.set(Calendar.DAY_OF_MONTH,2); System.out.println(calendar2.getTime().toLocaleString()); System.out.println(year+"年"+(month+1)+"月"+day+"日"+hour+"时"+minute+"分"+second+"秒"); //4.add方法修改时间 calendar2.add(Calendar.HOUR,1);//加一个小时 System.out.println(calendar2.getTime().toLocaleString()); //5.补充方法 int max = calendar2.getActualMaximum(Calendar.DAY_OF_MONTH);//获取Calendar.DAY_OF_MONTHde最大值 int min = calendar2.getActualMinimum(Calendar.DAY_OF_MONTH);//获取Calendar.DAY_OF_MONTHde最小值 System.out.println(max); System.out.println(min); } }
simpleDateFormat方法
package com.category.category_7; import java.text.SimpleDateFormat; import java.util.Date; public class Demo03 { public static void main(String[] args) throws Exception{ //创建SimpleDateFormat对象 表示以yyyy年MM月dd日HH:mm:ss格式输出 // SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); //2.创建Date Date date = new Date(); //格式化date(把日期转换成字符串) String str = sdf.format(date); System.out.println(str); //解析(把字符串转换成日期) Date date2 = sdf.parse("1990/05/01");//必须和sdf格式相符合!!! System.out.println(date2); } }
System类
package com.category.category_7; import java.util.Arrays; public class Demo04 { public static void main(String[] args) { //1.arraycopy,数组的复制 //src:复制的原数组 srcPos:从哪个位置开始复制第一个位置0 //dest:复制的目标数组 //destPos:目标数组的位置 //length:复制的长度 int[] arr = {1,2,3,4,5,6,7,8,9,10}; int[] dest = new int[10]; System.arraycopy(arr,4,dest,4,4); for (int i = 0; i < dest.length; i++) { System.out.println(dest[i]); } //Arrays.copyOf() //可以计算代码执行时间 System.out.println(System.currentTimeMillis()); long start = System.currentTimeMillis(); for (int i = 0; i < 999999; i++) { for (int j = 0; j < 999999; j++) { int result = i+j; } } long end = System.currentTimeMillis(); System.out.println("执行时间:"+(end - start)); //System.gc();告诉垃圾回收器回收 new Student("aaa", 12); new Student("bbb", 13); new Student("ccc", 14); System.gc(); //推出Jvm System.exit(0);//已经退出,后面不会执行 System.out.println("程序结束"); } }
package com.category.category_7; 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 void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected void finalize() throws Throwable { System.out.println("回收了"+name+""+" "+age); } }