什么是内部类
- 概念:在一个类的内部再定义一个完整的类。
特点:
- 编译之后可生成独立的字节码文件。
- 内部类可直接访问外部类的私有成员,而不破坏封装。
- 可为外部类提供必要的内部功能组件
成员内部类
- 在类的内部定义,与实例变量、实例方法同级别的类。
- 外部类的一个实例部分,创建内部类对象时,必须依靠外部类对象。
public class TestOuter{
public static void main(String[] args){
//1.创建外部类对象
Outer outer = new Outer();
//2.创建内部类对象
Inner inner = outer.new Inner();
//一步到位
Inner inner = new Outer().new Inner();
inner.show();
}
}
-
当外部类、内部类存在重名属性时,会优先访问内部类属性。如果还想访问外部类的同名属性需要(外部类的类名.this.属性名)
-
成员内部类当中不能定义静态类成员,但可以包含静态类常量
静态内部类
- 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。
//外部类
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(){
//调用外部类的属性,先创建外部类的对象
Outer outer = new Outer();
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 Inner.Outer();
// 调用内部类方法
inner.show();
}
}
- 只有内部类才可以用static修饰
局部内部类
- 定义在外部类的方法当中,作用范围和创建对象范围仅限于当前的方法。
- 局部变量,局部内部类不可以加访问修饰符
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。
- 限制类的使用范围,只能在当前方法中使用
//外部类
public class Outer{
private String name ="刘德华";
private int age =50;
public void show(){
//定义局部变量,
String address="祖国";//no static string address
//局部内部类:注意不能加任何访问修饰符
class Inner{//no static class Inner
//局部内部类的属性\不能加final,但可以加static final定义内部静态常量
private String phone ="1883838987";
private String email="37978493@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.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();
}
}
匿名内部类
- 没有类名的局部内部类(一切特征都与局部内部类相同)。
- 必须继承一个父类或者实现一个接口
- 定义类、实现类、创建对象的语法合并,只能创建一个类的对象。
- 优先:减少代码量。
- 缺点:可读性较差。
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类
-
超类、基类、所有类的直接或间接父类,位于继承树的最顶层。
-
任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则间为间接继承。
-
Object类中所定义的方法,是所有对象都具备的方法。
-
Object类型可以储存仍对象。
❂作为参数,可接受任何对象。
❂作为返回值,可返回任何对象。
getClass()方法
- 返回引用中储存的实际对象类型。
- 应用:通常用于判断两个引用中实际储存对象类型是否一致。
public class TestStudent{
public static void main(String[] args){
Student s1= new Student("aaa",20);
Student s2= new Student(bbb,22);
//判断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(){}
- 返回该对象的哈希码值。
- 哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int 类型的数值。
- 一般情况下相同对象返回相同哈希码
public class TestStudent{
public static void main(String[] args){
Student s1= new Student("aaa",20);
Student s2= new Student("bbb",22);
//判断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);
System.out.println(s2.hashCode);
Student s3=s1;
System.out.println(s3.hashCode());
}
}
toString()方法
- public String toString() {}
- 返回该对象的字符串表示(表现形式)。
- 可以根据程序需求覆盖该方法,如:展示对象各个属性值。
equals()方法
- public boolean equals (Object obj){}
- 默认实现为(this == obj),比较两个对象地址是否相同。
- 可进行覆盖,比较两个对象的内容是否相同。
equals方法覆盖步骤
比较两个引用是否指向同一个对象。
判断obj是否为null。
判断两个引用指向的实际对象类型是否一致。
强制类型转换。
依次比较各个属性值是否相同。
finalize()方法
- 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。
- 垃圾对象:没有有效引用指向此对象时,为垃圾对象。
- 垃圾回收:由GC销毁垃圾对象,释放数据存储空间。
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。
- 手动回收机制:使用System.gc(); 通知JVM执行垃圾回收。
什么是包装类
- 基本数据类型所对应的引用数据类型。
- Object可统一所有数据,包装类的默认值是null。
包装类对应
基本数据类型 | 包装类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
类型转换装箱、拆箱
-
8种包装类提供不同类型转换的方式:
Number父类中提供的6个共性方法。
parsexxx()静态方法。
valueOf()静态方法。
package com.xu.three.outer;
public class Demo01 {
public static void main(String[] args) {
//类型转换,装箱,基本类型转换成引用类型的过程
int num=18;
//使用Integer创建对象
Integer integer =new Integer(num );
Integer integer2 =Integer.valueOf(num );
//类型转换:拆箱,引用类型转换成基本类型
Integer integer3 =Integer .valueOf(num);
int num2 = integer3.intValue();
//JDK1.5之后,提供自动装箱和拆箱
int age = 30;
//自动装箱
Integer integer4 =age;
//自动拆箱
int age2 = integer4 ;
System.out.println("-------------------类型字符串之间转换--------------------");
//基本类型和字符串之间转换
//1基本类型转成字符串
int n1 =15;
//1.1使用+号
String s1=n1+"";
//1.2使用Integer中的toString()方法
String s2= Integer .toString(n1);
String s3 = Integer .toString(n1, 16);//表示n1的十六进制
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
//2.字符串转换成基本类型
String str = "25";
//使用Integer.parsexxx();
int str2 = Integer .parseInt(str);
System.out.println(str2);
//boolean 字符串形式转成基本类型:"true"----->true 非"true"------->false
String str3="true";
boolean b1 = Boolean .parseBoolean(str3);
System.out.println(b1);
}
}
整数缓冲区
- JAVA预先创建了256个常用的整数包装类型对象。
- 在实际应用当中,对 已创建的对象进行复用
String
- 字符串是常量,创建之后不可改变。
- 字符串字面值存储在字符串池中,可以共享。
- String s = “Hello”;产生一个对象,字符串池中储存
- String s = new String(“Hello”);//产生两个对象,堆、池各存储一个。
- 注意:(s1==s2)比的是内存空间的地址;(s1.equals(s2))比的是数据值!
常用方法
- length();返回字符串的长度
- charAt(int index);返回某个位置的字符
- contains(String str);判断是否包含某个字符
- toCharArray();返回字符串对应的数组
- indexOf();返回字符串首次出现的位置
- lastIndexOf();返回字符串最后一次出现的位置!
- trim();去掉字符串前后的空格
- toUpperCase();把小写转成大写
- toLowerCase();把大写转成小写
- endWhith(str);判断是否以str结尾
- starWhith(str);判断是否以str开头
- replace(char old,char new)用新的字符或者字符串替换旧的字符或者字符串
- split();对字符串进行拆分
- subString(int beginIndex)截取下标
package com.xu.three.outer;
import java.util.Arrays;
public class Demo02 {
public static void main(String[] args) {
/* //字符串方法的使用
1、length();返回字符串的长度
2、charAt(int index);返回某个位置的字符
3、contains (String str);判断是否包含某个字符串*/
String content="java是世界上最好的java编程语言,java真香";
System.out.println(content.length());
System.out.println(content .charAt(content .length()-1));
System.out.println(content .charAt(0));
System.out.println(content.contains("java"));
System.out.println(content.contains("php"));
System.out.println("-------------------字符串的使用方法2--------------------");
//4.toCharArray();返回字符串对应的数组
//5.indexOf();返回字符串首次出现的位置
//6.lastIndexOf();返回字符串最后一次出现的位置
System.out.println(Arrays.toString(content .toCharArray()));
System.out.println(content .indexOf("java"));
System.out.println(content .indexOf("java",4));
System.out.println(content .lastIndexOf("java"));
System.out.println("----------------字符串方法的使用3------------------");
//7.trim();去掉字符串前后的空格
//8.toUpperCase();把小写转成大写toLowerCase();把大写变成小写
//9.endWith(str);判断是否已str结尾,starWith(str);判断是否已str开头
String content2=" hello world ";
System.out.println(content2.trim());
System.out.println(content2.toUpperCase());
System.out.println(content2.toLowerCase());
String filename="hello.java";
System.out.println(filename.endsWith("hello"));
System.out.println(filename.startsWith("hello"));
System.out.println("-------------------字符串方法的使用4------------------------");
//10.replace(char old , char new);用新的字符或者字符串替换旧的字符或字符串
//11.split();对字符串进行拆分
System.out.println(content.replace("java", "php"));
String say = "java is the best programing language,java xiang";
String[] arr = say.split("[ ,]+");
System.out.println(arr.length);
for (String string : arr) {
System.out.println(string);
}
//补充两个方法equals、compareTo();比较大小
System.out.println("--------------------------补充-------------------------");
String s1 = "hello";
String s2 = "Hello";
System.out.println(s1.equals(s2));
System.out.println(s1.equalsIgnoreCase(s2));//忽略大小写!
String s3 = "abc";//a97
String s4= "xyz";//x120
System.out.println(s3.compareTo(s4));//比的是第一个字符编码中的位置
String s5 = "abc";
String s6 = "abcxyz";
System.out.println(s5.compareTo(s6));//这个时候比的是字符串的长度
}
}
案例演示
需求;
- 已知String str = “this is a text”;
-
- 将str中的单词单独获取 出来
- 将str中的text替换为practice
- 在text前面插入一个easy
- 将每个单词的首字母改为大写
package com.xu.three.outer;
public class Demo03 {
public static void main(String[] args) {
String str = "this is a text";
String[] str2=str.split(" ");
for (String string : str2) {
System.out.println(string);
}
System.out.println(str.replace("text", "practice"));
System.out.println(str.replace("text", "easy text"));
for (int i = 0; i < str2.length; i++) {
char first = str2[i].charAt(0);
char upperfirst=Character.toUpperCase(first);
String str3 = upperfirst+str2[i].substring(1);
System.out.println(str3);
}
}
}
可变字符串
- StringBuffer:可变长字符串,JDK1.0提供,运行效率慢、线程安全。
- StringBuilder:可变长字符串,JDK5.0提供,运行效率快、线程不安全。
BigDecimal
-
位置:java.math包中
-
作用:精确计算浮点数。
-
创建方式:Big Decimal bd = new BigDecimal(“1.0”);
-
除法:divide(BigDecimal bd,int scal,RoundingMode mode)
-
参数scal:指定精确到小数点后几位。
-
参数mode:
指定小数部分的取舍模式,通常采用四舍五入的模式、
取值为BigDecimal.ROUND_HALF_UP
Date
-
Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已经被Calendar类中的方法所取代。
-
时间单位
1秒=1000毫秒
1毫秒=1000微秒
1微秒=1000纳秒
Calendar
-
Calendar提供了获取或设置各种日历字段的方法。
-
构造方法
protected Calendar() ;由于修饰符是protected,所以无法直接创建该对象。
package com.xu.three.outer;
import java.util.Calendar;
public class Demo08 {
public static void main(String[] args) {
//1.创建Calendar对象
Calendar calendar = Calendar .getInstance();
System.out.println(calendar .getTime().toString());
System.out.println(calendar .getTimeInMillis());
//获取时间信息
//获取年
int year = calendar.get(Calendar .YEAR);
//月
int month = calendar .get(Calendar .MONTH);
//日
int day = calendar .get(Calendar .DAY_OF_MONTH);
//小时
int hour = calendar .get(Calendar .HOUR_OF_DAY);//HOUR12小时制。HOUR_OF_DAY24小时制
//分钟
int minute = calendar .get(Calendar .MINUTE);
//秒
int second = calendar .get(Calendar .SECOND);
System.out.println(year +"年"+month+"月"+day+"日"+hour+":"+minute+":"+second);
//修改时间
Calendar calendar2 = Calendar .getInstance();
calendar2.set(Calendar .MONTH, 2);
System.out.println(calendar2.getTime().toLocaleString());
//add修改时间
calendar2.add(Calendar .HOUR, 1);
System.out.println(calendar2.getTime().toLocaleString());
//补充方法
int max = calendar2.getActualMaximum(Calendar.DAY_OF_MONTH);
int min = calendar2.getActualMinimum(Calendar .DAY_OF_MONTH);
System.out.println(max);
System.out.println(min);
}
}
SimpleDateFormat
- SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类。
- 进行格式化(日期->文本)、解析(文本->日期)。
System类
- System系统类,主要用于获取系统的属性数据和其他操作,构造方法私有的。
package com.xu.three.outer;
public class Demo10 {
public static void main(String[] args) {
//arraycopy:数组的复制
//src:原数组,srcPos:从那个位置开始复制0,dest:目标数组,destPos:,目标数组的位置,length:复制的长度
int[] arr = {20,18,15,8,35,26,45,90};
int[] dest = new int[8];
System.arraycopy(arr, 4, dest, 4, 4);
for (int i = 0; i < dest.length; i++) {
System.out.println(dest[i]);
}
System.out.println(System.currentTimeMillis());
//获取毫秒数
long start = System.currentTimeMillis();
for (int i = 0; i < 99999999; i++) {
for (int j = 0; j < 99999999; j++) {
int result = i+j;
}
}
long end = System.currentTimeMillis();
System.out.println("用时"+(end-start));
//System.gc();告诉垃圾回收
System.exit(0);//退出jvm
System.out.println("垃圾回收了");
}
}