JavaSE:经典接口、包装类、枚举、内部类

一、经典接口

1、java.lang.Comparable接口:自然排序/比较接口,或者也称为默认排序
抽象方法:int compareTo(Object o)
返回值结果: .前面的this 大于 ()中的指定对象o, 返回正整数
返回值结果: .前面的this 小于 ()中的指定对象o, 返回负整数
返回值结果: .前面的this 等于 ()中的指定对象o, 返回0

2、java.util.Comparator接口:定制排序/比较接口,或者也称为挽救的比较器
抽象方法:int compare(Object o1, Object o2)
返回值结果: o1 大于 o2, 返回正整数
返回值结果: o1 小于 o2, 返回负整数
返回值结果: o1 等于 o2, 返回0

二、包装类

1.、包装类是什么?

byte–>Byte
short–>Short
int–>Integer
long–>Long
float–>Float
double–>Double
char–>Character
boolean–>Boolean
void–>Void

2、如何使用包装类

(1)普通使用
Integer obj = new Integer(xx);

(2)和基本数据类型转换
装箱:
基本数据类型 --> 包装类的对象
拆箱:
包装类对象 --> 基本数据类型

手动装箱:
①用包装类的构造器,用基本数据类型的值/变量创建一个包装类对象
②用包装类的valueOf方法,把基本数据类型的值/变量转变为一个包装类对象 since1.5从JDK1.5之后才有
自动装箱:JDK1.5之后
①当把基本数据类型的值/变量赋值给引用数据类型的变量时,自动会装箱
②每一种基本数据类型只与自己的包装类之间进行自动装箱

手动拆箱:
①包装类对象调用xxValue()
例如:Integer的对象,可以调用 .intValue()返回int值
自动拆箱:
①当把包装类的对象赋值给基本数据类型的变量时,会自动拆箱
②当包装类的对象遇到基本数据类型的运算符(>,<等)时,会自动拆箱

总结:数据类型的转换
(1)基本数据类型之间 :自动类型升级和强制类型转换
(2)引用数据类型之间:要求父子类,而且是编译时的转换,向上转型和向下转型
(3)基本数据类型与包装类之间:装箱与拆箱
(4)其他类型与字符串之间:
其他类型 -> 字符串:
①所有类型 + 字符串 结果就是字符串
②引用数据类型的对象.toString() 就是专为字符串
字符串 -> 其他类型
调用对应的parseXxx方法

public class TestWrapper {
    public static void main(String[] args) {
        Integer obj1 = new Integer(1);
        Integer obj2 = new Integer(1);
        System.out.println(obj1.equals(obj2));

        System.out.println("----------------------------");
        int a = 10;
//        method(a);//JDK1.5之前  错误,a不是引用数据类型
        //用构造器
//        Integer obj = new Integer(a);
//        method(obj);

        //用valueOf方法
//        Integer obj = Integer.valueOf(a);
//        method(obj);

        method(a);//class java.lang.Integer

        System.out.println("----------------------------");
        int num = 1;
//        Double value = num; //num是int,它只会自动装箱为Integer的对象,而Integer的对象是不能赋值给Double
        double d = num; //num自动类型升级为double
        Double value = d;

        System.out.println("----------------------------");
        Integer obj3 = new Integer(30);
        Integer obj4 = new Integer(30);
        //手动拆箱
        System.out.println(obj3.intValue() > obj4.intValue());
        //自动拆箱
        System.out.println(obj3 > obj4);

        /*String str1 = "10";
        String str2 = "10";
        System.out.println(str1 > str2);*///不是包装类,就不会自动拆箱
    }

    public static void method(Object obj){
        //....
        //获取obj的运行时类型
        System.out.println(obj.getClass());
    }
}

3.包装类的缓存问题

Byte:-128~127
Short:-128~127
Integer:-128~127
Long:-128~127
Character:0~127 最早的ASCII表的范围。
Float和Double不缓存。
Boolean:true和false

4.包装类的方法

例如:Integer
(1)把字符串转为基本数据类型或它的包装类对象(几乎所有包装类都有对应)(重要)
①构造器
Integer obj = new Integer(字符串);
②valueOf方法
Integer obj = Integer.valueOf(字符串);
③parseInt方法
int value = Integer.parseInt(字符串)

(2)其他方法(不一定有通用性)(了解)

(3)比较两个基本数据类型的值(重要)
特别是double和float类型
例如:Double.compare(x,y)返回正、负、0整数

(4)转字母大小写 (Character) 重要
//方式一:
System.out.println((char)(letter-32));
//方式二:
System.out.println(Character.toUpperCase(letter));
(5) 获取每一种数据类型的最大值和最小值(了解 )

三、枚举

Java的数据类型:
1、基本数据类型
2、引用数据类型:
数组、类、接口、枚举、注解

1、什么是枚举类型?

其实本质上枚举也是一种类。
特殊:
(1)这种类型的对象是在整个程序中只有固定的有限的几个常量对象。
例如:星期、月份、季节、员工状态、订单状态等
(2)JDK1.5之后声明它的关键字从class变为enum

语法格式:
【修饰符】 enum 枚举类名{
常量对象列表 【;

其他成员;
】

}

说明:
(1)常量对象列表中每一个常量之间使用,分割,如果常量对象列表后面没有其他代码了,就不用加;,
如果常量对象列表后面还有其他代码,那么在常量对象列表最后要加一个;
(2)常量对象必须在枚举类中首行
(3)用enum声明的枚举类型,构造器自动私有化,无论你是否加private
(4)用enum声明的枚举类型,不能再继承其他类了,因为它默认的直接父类是java.lang.Enum
①父类中有两个成员变量:name,value
name是常量对象名,value是常量对象的序号,从0开始
②Enum类中重写了Object类的toString,默认返回的是对象的name
③在API中看不到的两个方法
static 枚举类型 valueOf(String name)
static 枚举类型[] values()
④switch在JDK1.5之后支持了枚举类型

回忆:首行
(1)super()和super(…)必须在子类构造器的首行
(2)this()和this(…)必须在本类构造器的首行
(3)package必须在.java源文件的代码首行
(4)枚举常量对象必须在枚举类的首行

四、内部类

1、静态内部类语法格式

【修饰符】 class 外部类{
【其他修饰符】 static class 内部类{
}
}

2、静态内部类特点

(1)静态内部类的权限修饰符:4种
(2)静态内部类也是一个类
①有自己的字节码文件,名字是 外部类名$静态内部类名.class
②类中的所有成员它都可以声明
③可以是abstract,可以是final
④继承自己的父类,实现接口们
⑤可以创建对象,只要它不是抽象的

(3)如何使用它
在外部类中使用静态内部类:
使用静态的成员:直接静态内部类名.成员
使用非静态的成员:先创建静态内部类的对象,然后对象.成员
在外部类的外面静态内部类:
使用静态的成员:直接静态内部类名.成员
使用非静态的成员:先创建静态内部类的对象,然后对象.成员
只不过在外面使用静态内部类时,要加外部类名.静态内部类名

(4)在静态内部类中使用外部类的成员
虽然说可以直接使用外部类的私有成员,但是在静态内部类中不能直接使用外部类的非静态成员。

(5)在外部类中使用静态内部类的成员

​ 在外部类中也可以使用静态内部类的私有成员

public class TestStatic {
    public static void main(String[] args) {
        Outer.outMethod();

        //直接在这里使用静态内部类
        //(1)在这里调用Inner的inMethod()
        Outer.Inner.inMethod();

        //(2)在这里调用Inner的inTest()
        Outer.Inner inner = new Outer.Inner();
        inner.inTest();
    }
}

class Outer{
    private int a;
    private static int b;

    static class Inner{
        private int c = 3;
        private static int d = 4;
        public static void inMethod(){
            System.out.println("静态内部类的静态方法");
//            System.out.println("外部类的a = " + a);
            System.out.println("外部类的b = " + b);
        }
        public void inTest(){
            System.out.println("静态内部类的非静态方法");
//            System.out.println("外部类的a = " + a);
            System.out.println("外部类的b = " + b);
        }
    }

    public static void outMethod(){
        //在这里使用Inner
        //在这里调用Inner的inMethod()
//        Inner.inMethod();

        //在这里调用Inner的inTest()
        Inner inner = new Inner();
        inner.inTest();

        //在这里使用Inner的private的c和d
        System.out.println(inner.c);
        System.out.println(Inner.d);
    }
}
2.非静态内部类

1、语法格式
【修饰符】 class 外部类{
【修饰符】 class 内部类{
}
}

2、特点
(1)权限修饰符:4种
(2)非静态内部类也是一个类
①也有自己的字节码文件,外部类名$非静态内部类名.class
②非静态内部类中不能静态的成员(静态变量、静态方法、静态代码块、静态内部类)
但是,如果该静态成员是从父类继承的,可以
可以声明静态的常量
③可以是abstract,可以是final
④继承自己的父类,实现接口们
⑤可以创建对象,只要它不是抽象的

(3)在外部类中使用非静态内部类
在外部类的非静态方法中使用:先创建非静态内部类的对象,然后用对象.成员
在外部类的静态方法中使用:不能

(4)在外部类的外面使用非静态内部类
第一步:创建外部类的对象
第二步:获取内部类的对象
要么直接new,要么通过外部类的对象.方法获取内部类对象
第三步:通过内部类的对象.成员

总结:
拿到一个类型的对象的几种形式:
(1)直接new
变量 = new 类名(…);
(2)枚举类名.常量对象
变量 = 枚举类名.常量对象名;
(3)其他对象.方法(…) 该方法可以返回某个类型的对象
变量 = 其他对象.方法(…);

(5)外部类和非静态内部类可以互访私有成员
*/

public class TestNonStatic {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.outMethod();

        //在这里调用Inner的inMethod()
//        Outer.Inner inner = new Outer.Inner();//错误,因为Inner是作为Outer的非静态成员,所以需要Outer的对象
        Outer out = new Outer();
        Outer.Inner inner = out.new Inner();
        inner.inMethod();

        System.out.println("-------------------------------");
        //在这里调用Inner的inMethod(),但是想要避免 out.new Inner() 这种写法
        Outer out2 = new Outer();
        Outer.Inner inner2 = out2.getInner();
        inner2.inMethod();
    }
}

class Outer{
    private int a;
    private static int b;

    class Inner {
        private int c;

        public void inMethod(){
            System.out.println("非静态内部类的非静态方法");
            System.out.println("外部类的a =" + a);
            System.out.println("外部类的b =" + b);
        }
    }

    public void outMethod(){
        //在这里调用Inner的inMethod()
        Inner inner = new Inner();
        inner.inMethod();

        System.out.println("使用内部类的c = " + inner.c);
    }

    public static void outTest(){
        //在这里调用Inner的inMethod()
//        Inner inner = new Inner();//错误,因为outTest()方法是静态的,Inner是非静态
    }

    //调用这个方法,可以获取Inner的对象
    public Inner getInner(){
        return new Inner();
    }
}

3.局部内部类(了解)

1、语法格式:
【修饰符】 class 外部类{
【修饰符】 返回值类型 方法名(【形参列表】){
【修饰符】 class 内部类{
}
}
}

2、特点
(1)权限修饰符:没有权限修饰符
(2)局部内部类也是一个类
①有自己的字节码文件,外部类名$编号局部内部类名.class
为什么有编号?因为同一个外部类中可能存在同名的多个局部内部类
②局部内部类中不能静态的成员(静态变量、静态方法、静态代码块、静态内部类)
但是,如果该静态成员是从父类继承的,可以
可以声明静态的常量
③可以是abstract,可以是final
④继承自己的父类,实现接口们
⑤可以创建对象,只要它不是抽象的

(3)在外部类中使用局部内部类
有作用域,仅限在作用域范围内使用

(4)在外部类的外面使用局部内部类

(5)那么能否在外部类的外面,获取到局部内部类的对象?
或者说,如果想要把局部内部类的对象,返回到外部类的外面使用,是否可以呢?
可以,通过方法的返回值返回内部类的对象,而且方法的返回值只能是它的父类或父接口类型。

(6)外部类和局部内部类可以互访私有的成员
但是:如果局部内部类是在静态方法中,不能使用外部类的非静态成员。

(7)局部内部类可以访问外部类的局部变量,但是是要注意作用域(特殊)
注意:该局部变量必须是final的。
JDK1.8之前必须手动加final,JDK1.8之后自动加final。

为什么呢?
如果把局部内部类的对象,返回到外部类的外面使用时,那么如果在局部内部类中使用了局部变量,
当返回局部内部类对象的方法运行结束之后,该局部变量的内存是会随着方法的出栈而消失,
那么就会出现访问不存在的内存问题。
此时其实编译帮局部内部类自动声明了一个隐形的成员变量,和刚刚的局部变量同名,初始化它的值。
所以避免认为是同一个值不统一问题,干脆规定值不能修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值