• 17_内部类和常用类


    一. 内部类

    概念:

    • 在一个类的内部再定义一个完整的类

    特点:

    • 编译之后可生成独立的字节码文件
    • 内部类可直接访问外部类的私有成员,而不破坏封装

    1. 成员内部类

    • 在类的内部定义,与实例变量、实例方法同级别的类
    • 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象
      • Outer out = new Outer();
      • Inner in = out.new Inner();
    • 当外部类、内部类存在重名属性时,会优先访问内部类属性
    • 成员内部类不能定义静态成员,但可以定义静态常量

    2. 静态内部类

    • 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
    • 只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
      • Outer.Inner inner = new Outer.Inner();
      • Outer.Inner.show();

    3. 局部内部类

    • 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法

    • 不能加任何访问修饰符

    • 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final(jdk1.8以后隐式添加final)

    • 限制类的使用范围

    4. 匿名内部类

    • 没有类名的局部内部类(一切特征都与局部内部类相同)
    • 必须继承一个父类或者实现一个接口
    • 定义类、实现类、创建对象的语法合并、只能创建一个该类的对象
    • 优点:减少代码量
    • 缺点:可读性较差

    二. 常用类

    1. Object

    • 超类、基类,所有类的直接或间接父类,位于继承树的最顶层
    • 任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承
    • Object类中所定义的方法,是所有对象都具备的方法
    • Object类型可以存储任何对象
      • 作为参数,可接受任何对象
      • 作为返回值,可返回任何对象

    (1) getClass()方法

    • public final CLass<?> getClass() {}
    • 返回引用中存储的实际对象类型
    • 应用:通常用于判断两个引用中实际存储对象类型是否一致

    (2) hashCode()方法

    • public int hashCode() {}
    • 返回该对象的哈希码值
    • 哈希值根据对象的地址字符串数字使用hash算法计算出来的int类型的数值
    • 一般情况下相同对象返回相同哈希码

    (3) toString()方法

    • public String toString () {}
    • 返回该对象的字符串表示(表现形式)
    • 可以根据程序需求覆盖该方法,如:展示对象各个属性值

    (4) equals()方法

    • public boolean equals (Object obj) {}
    • 默认实现为(this == obj),比较两个对象地址是否相同
    • 可进行覆盖,比较两个对象的内容是否相同

    (5) finalize()方法

    • 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
    • 垃圾对象:没有有效引用指向此对象时,为垃圾对象
    • 垃圾回收:由Gc销毁垃圾对象,释放数据存储空间
    • 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
    • 手动回收机制:使用System.gc(); 通知JVM执行垃圾回收
    public class TestStudent {
    
        public static void main(String[] args) {
    
            System.out.println("=====getClass()方法=====");
            //1. getClass()方法
            Student s1 = new Student("张三", 18);
            Student s2 = new Student("李四", 19);
    
            //判断s1和s2是否是同一类型
            Class class1 = s1.getClass();
            Class class2 = s2.getClass();
            if (class1 == class2){
                System.out.println("student和student1属于同一类型");//student和student1属于同一类型
            }else{
                System.out.println("student和student1不属于同一类型");
            }
    
            System.out.println("=====hashCode()方法=====");
            //2. hashCode()方法
            System.out.println(s1.hashCode());
            System.out.println(s2.hashCode());
    
            Student s3=s1;
            System.out.println(s3.hashCode());
    
            System.out.println("=====toString()方法=====");
            //3. toString()方法
            System.out.println(s1.toString());
            System.out.println(s2.toString());
    
            System.out.println("=====equals()方法=====");
            //4. equals()方法
            System.out.println(s1.equals(s2));
            Student s4 = new Student("王五", 20);
            Student s5 = new Student("王五", 20);
            System.out.println(s4.equals(s5));
    
        }
    }
    

    2. 包装类

    • 基本数据类型所对应的引用数据类型
    • Object可统一所有数据,包装类的默认值是null
    基本数据类型 包装类型
    byte Byte
    short Short
    int Integer
    long Long
    float Float
    double Double
    boolean Boolean
    char Character

    类型转换

    基本类型和引用类型

    装箱:基本类型转成引用类型的过程

    拆箱:引用类型转成基本类型的过程

    public class Demo01 {
    
        public static void main(String[] args) {
    
            //JDK 1.5之前
            //类型转换
            //装箱:基本类型转成引用类型的过程
            int num = 10;
            Integer integer = new Integer(num);
            Integer integer1 =  Integer.valueOf(num);
            System.out.println("装箱");
            System.out.println(integer);
            System.out.println(integer1);
            //类型转换
            //拆箱:引用类型转成基本类型的过程
            Integer integer2 = new Integer(100);
            int num2 = integer2.intValue();
            System.out.println("拆箱");
            System.out.println(num2);
    
            //JDK1.5之后,提供自动装箱和开箱功能
            int age = 30;
            //自动装箱
            Integer integer3 = age;
            System.out.println("自动装箱");
            System.out.println(integer3);
            //自动拆箱
            int age2 = integer3;
            System.out.println("自动拆箱");
            System.out.println(age2);
    
            //1. 基本类型转字符串
            //1.1 使用“+”
            int i = 255;
            int i1 = 1;
            System.out.println(i+i1+"");//256 字符串在后面,相加
            System.out.println(""+i+i1);//2551 字符串在前面,拼接
            String s = i + "";
            System.out.println(s);//255
    
            //1.2 Integer.toString()
            String s2 = Integer.toString(i);
            System.out.println(s2);//255
            //toString重载,输出i的radix进制数
            String s3 = Integer.toString(i, 16);
            System.out.println(s3);//ff
    
            //2. 字符串转基本类型
            String str = "100";
            //使用Integer.parseInt()
            int i2 = Integer.parseInt(str);
            System.out.println(i2);//100
    
            //boolean字符串形式转成基本类型,"true"=>true,只要不是"true",都是false
            String str2 = "true";
            boolean b = Boolean.parseBoolean(str2);
            System.out.println(b);//true
        }
    }
    

    整数缓冲区(-128~127)

    • java预先创建了256个常用的整数包装类型对象
    • 在实际应用当中,对已创建的对象进行复用
    public class Demo02 {
    
        public static void main(String[] args) {
    
            //Integer缓冲区-128~127
            Integer integer = new Integer(100);
            Integer integer1 = new Integer(100);
            System.out.println(integer == integer1);//false
    
            Integer integer2 = Integer.valueOf(100);
            Integer integer3 = Integer.valueOf(100);
            //在缓冲区里,值一样,引用对象也相同
            System.out.println(integer2 == integer3);//true
    
            Integer integer4 = Integer.valueOf(100);
            Integer integer5 = Integer.valueOf(100);
            //不在缓冲区里,则重新在堆里面new一个对象,所以两个不同的对象的引用也不同
            System.out.println(integer4 == integer5);//false
    
        }
    }
    

    3. String

    • 字符串是常量,创建后不可改变
    • 字符串字面值存储在字符串池中,可以共享

    常量池概念:

    ​ Java运行时会维护一个String Pool(String池), 也叫“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。

    String对象的创建很讲究,关键是要明白其原理。

    原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个s在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。

    原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。

    原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。

    原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。最后指向堆内存中的对象

    public class Demo01 {
    
        public static void main(String[] args) {
    
            //1. 先定义一个名为str的对String类的对象引用变量:String str;
            String str1 = "aaa";//字符串常量存储在方法区的字符串池中
            //2. 在池中查找有没有存放值为"aaa"的地址,如果没有,则开辟一个存放字面值为"aaa"的地址
            //接着创建一个新的String类的对象o,并将o 的字符串值指向这个地址,而且在池中这个地址旁边记下这个引用的对象o。如果已经有了值为"aaa"的地址,则查找对象o,并返回o的地址。
            //3. 将str指向对象o的地址
            //当我们将str1的值改为"bbb"时,JVM发现在池中没有存放该值的地址,便开辟了一个存放字面值为"bbb"的地址,并创建了一个新的对象,其字符串的值指向这个地址
    
            str1 = "bbb";
    
            String str2 = "bbb";//JVM 创建str2,并指向“bbb”
            System.out.println(str1 == str2);//true
            //总结就是:JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象
    
            //1、 使用new关键字
    
            String s1 = new String("ab"); //产生两个对象,堆、池中各存一个
    
            //2、 使用字符串常量直接赋值
    
            String s2 = "abc";
    
            //3、 使用”+”运算符进行字符串连接
    
            String s3 = "abc" + "d";
    
            String s4 = s3 + 5; //abcd5
    
            System.out.println("=======================");
    
            String n1 = new String("java");
            String n2 = new String("java");
            System.out.println(n1 == n2);//false,n1和n2分别指向堆中的两个对象
            System.out.println(n1.equals(n2));//true
    
        }
    }
    

    (1)常用方法

    - public int length():返回字符串的长度
    - public char charAt(int index):根据下标获取字符
    - public boolean contains(String str):判断当前字符串是否包含str
    - public char[] toCharArray():将字符串转化为数组
    - public int indexOf(String str):查找str首次出现的下标,存在,则返回该下标;不存在,则返回-1
    - public int lastIndexOf(String str):查找str最后一次出现的下标索引
    - public String trim():去掉字符串前后的空格
    - public String toUpperCase():将小写转成大写
    - public boolean endWith(String str):判断字符串是否以str结尾
    - public String replace(char oldChar,char newChar):将旧字符串替换成新的字符串
    - public String[] split(String str):根据str做拆分
    - public String substring(int beginIndex, int endIndex):截取父字符串的一部分,结尾参数可去掉
    
    public class Demo02 {
    
        public static void main(String[] args) {
    
            //1. length():返回字符串的长度
            //2. charAt(int index):根据下标获取字符
            //3. contains(String str):判断当前字符串是否包含str
    
            String s = "java是世界上最好的语言";
            System.out.println(s.length());//13
            System.out.println(s.charAt(0));//首位字符 j
            System.out.println(s.charAt(s.length()-1));//末尾字符 言
            System.out.println(s.contains("java"));//true
            System.out.println(s.contains("Php"));//false
    
            //4. toCharArray():将字符串转化为数组
            //5. indexOf(String str):查找str首次出现的下标,存在,则返回该下标;不存在,则返回-1
            //6. lastIndexOf(String str):查找str最后一次出现的下标索引
    
            System.out.println(Arrays.toString(s.toCharArray()));//[j, a, v, a, 是, 世, 界, 上, 最, 好, 的, 语, 言]
            System.out.println(s.indexOf("a"));//1
            System.out.println(s.lastIndexOf("a"));//3
    
            //7. trim():去掉字符串前后的空格
            //8. toUpperCase():将小写转成大写
            //9. endWith(String str):判断字符串是否以str结尾
    
            String s2 = "  asd   ";
    
            String s3 = s2.trim();
            System.out.println(s3);//asd
    
            String s4 = s3.toUpperCase();
            System.out.println(s4);//ASD 转为大写字母
    
            String s5 = s4.toLowerCase();
            System.out.println(s5);//asd 转为小写字母
    
            String filename = "hello.java";
            System.out.println(filename.endsWith(".java"));//true
    
            //10. replace(char oldChar,char newChar):将旧字符串替换成新的字符串
            //11. split(String str):根据str做拆分
    
            System.out.println("==========");
            System.out.println(s.replace("java","php"));
    
            String s1 = "java is the best  language of the world,  java is good";
            String[] arr = s1.split("[ ,]+");//[ ,]表示以空格或者逗号作为分隔符,+表示空格和逗号可以出现多次
            System.out.println(arr.length);//11
            for (String s6 : arr) {
                System.out.println(s6);
    
            }
            //字符串String的split方法, 传入的分隔字符串是正则表达式!
            // 部分关键字(比如.[]()|等)需要转义
            String str = "a.ab.abc";
            String str1 = "a|ab|abc";
            System.out.println(Arrays.toString(str.split("\.")));//[a, ab, abc]
            System.out.println(Arrays.toString(str1.split("\|")));//[a, ab, abc]
    
            //补充:equals,compareTo()
            System.out.println("---------------");
            String s6 = "hello";
            String s7 = "Hello";
            System.out.println(s6.equalsIgnoreCase(s7));//true 忽略大小写
    
            String s8 = "abc";//97
            String s9 = "xyz";//120
            System.out.println(s8.compareTo(s9));//-23
    
            String s10 = "abc";//3
            String s11 = "abcxyz";//6
            System.out.println(s10.compareTo(s11));//-3,比较长度
    
        }
    }
    
    public class TestDemo02 {
    
        public static void main(String[] args) {
    
            String str = "this is a text";
            //1.将str中的单词单独获取出来
            String[] arr = str.split(" ");
            for (String s : arr) {
                System.out.println(s);
            }
            //2.将str中的text替换为practice
            String str2 = str.replace("text", "practice");
            System.out.println(str2);
    
            //3.在text前面插入一个easy
            String str3 = str.replace("text", "easy text");
            System.out.println(str3);
    
            //4.将每个单词的首字母该为大写
            //substring截取父字符串的一部分
            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);
    
            }
        }
    }
    

    (2)StringBuffer和StringBuilder

    • StringBuffer:可变长字符串,JDK1.0提供,运行效率慢、线程安全
    • StringBuilder:可变长字符串,JDK5.0提供,运行效率块、线程不安全
    public class Demo03 {
    
        public static void main(String[] args) {
    
            StringBuilder sb = new StringBuilder();
            //1. append(); 追加
            sb.append("张三");
            System.out.println(sb.toString());
            sb.append("李四");
            System.out.println(sb.toString());
            sb.append("王五");
            System.out.println(sb.toString());
            //2. insert(); 添加
            sb.insert(0, "第一");
            System.out.println(sb.toString());
            //3. replace(); 替换
            sb.replace(0,2,"第二");
            System.out.println(sb.toString());
            //4. delete(); 删除
            sb.delete(0,2);
            System.out.println(sb.toString());
        }
    }
    
    //测试StringBuilder和String的速度
    public class TestDemo03 {
    
        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);//28791 String用时28.791秒
    
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < 99999; i++) {
                stringBuilder.append(i);
            }
            System.out.println(stringBuilder);//74 StringBuilder用时0.074秒,速度比String快太多了
    
            long end = System.currentTimeMillis();
            System.out.println("用时:" + (end - start));
    
        }
    
    }
    
    

    4.BigDecimal

    • 位置:java.math包中
    • 作用:精确计算浮点数
    • 创建方式:BigDecimal bd = new BigDecimal("1.0");
    public class Demo01 {
    
        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);
    
            //BigDecimal 大的浮点数的精确计算
            BigDecimal bd = new BigDecimal("1.0");
            BigDecimal bd1 = new BigDecimal("0.9");
    
            //加法
            BigDecimal r1 = bd.add(bd1);
            System.out.println(r1);
    
            //减法
            BigDecimal r = bd.subtract(bd1);
            System.out.println(r);
    
            //乘法
            BigDecimal r2 = bd.multiply(bd1);
            System.out.println(r2);
    
            //除法
            BigDecimal result1 = new BigDecimal("1.4")
                    .subtract(new BigDecimal("0.5"))
                    .divide(new BigDecimal("0.9"));
            System.out.println(result1);
    
            BigDecimal result2 = new BigDecimal("20").divide(new BigDecimal("3"), 2, BigDecimal.ROUND_HALF_UP);
            System.out.println(result2);
            //除法:divide(BigDecimal bd, int scale, RoundingMode mode)
            //参数scale:指定精确到小数点后几位
            //参数mode:指定小数部分的取舍模式,通常采用四舍五入模式,取值为BigDecimal.ROUND_HALF_UP
        }
    }
    

    5. Date

    • Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已被Calendar类中的方法所取代
    • 时间单位
      • 1秒=1000毫秒
      • 1毫秒=1000微秒
      • 1微秒=1000纳秒
    public class Demo01 {
    
        public static void main(String[] args) {
    
            //1.创建Date对象
            Date date = new Date();
            System.out.println(date.toString());
            System.out.println(date.toLocaleString());
    
            Date date1 = new Date(date.getTime()-(60*60*24*1000));
            System.out.println(date1.toLocaleString());
    
            //2.方法after before
            boolean b1 = date.after(date1);
            System.out.println(b1);
            boolean b2 = date.before(date1);
            System.out.println(b2);
    
            //比较 compareTo()
            int i = date.compareTo(date1);
            System.out.println(i);
    
            //equals()
            boolean b = date.equals(date1);
            System.out.println(b);
    
        }
    }
    

    6. Calendar

    • Calendar提供了获取或设置各种日历字段的方法
    • 构造方法
      • protected Calendar():由于修饰符是protected,所以无法直接创建该对象
    public class Demo01 {
    
        public static void main(String[] args) {
    
            //1. 创建Calendar
            Calendar calendar = Calendar.getInstance();
            System.out.println(calendar.getTime().toLocaleString());
            System.out.println(calendar.getTimeInMillis());
            //2. 获取时间信息
            //获取年
            int year = calendar.get(Calendar.YEAR);
            //月
            int month = calendar.get(Calendar.MONTH);
            //日
            int day = calendar.get(Calendar.DAY_OF_MONTH);//DATE
            //小时
            int hour = calendar.get(Calendar.HOUR_OF_DAY);//HOUR_OF_DAY 24h,HOUR 12h
            //分钟
            int minute = calendar.get(Calendar.MINUTE);
            //秒
            int second = calendar.get(Calendar.SECOND);
            System.out.println(year + "-" +
                    (month+1) + "-" +
                    day + " " +
                    hour + ":" +
                    minute + ":" +
                    second);
            //3. 修改时间 set
            Calendar calendar1 = Calendar.getInstance();
            calendar1.set(Calendar.DAY_OF_MONTH, 23);//日期变为23号
            System.out.println(calendar1.getTime().toLocaleString());
    
            //4. 修改时间 add
            calendar1.add(Calendar.HOUR, -1);//减少一小时
            System.out.println(calendar1.getTime().toLocaleString());
    
            //5. 补充方法
            int max = calendar1.getActualMaximum(Calendar.DAY_OF_MONTH);//计算本月最大天数
            int min = calendar1.getActualMinimum(Calendar.DAY_OF_MONTH);//计算本月最小天数
            System.out.println(max);
            System.out.println(min);
    
    
        }
    }
    

    7.SimpleDateFormat

    • SimpleDateFormat是一个以 与语言环境有关的方式 来 格式化和解析日期 的具体类
    • 进行格式化(日期 -> 文本)、解析(文本 -> 日期)
    • 常用的时间模式字母
    字母 日期或时间 示例
    y 2021
    M 年中月份 02
    d 月中天数 24
    H 1天中小时数(0~23) 11
    m 分钟 46
    s 59
    S 毫秒 345
    public class Demo01 {
    
        public static void main(String[] args) throws ParseException {
    
            //1. 创建SimpleDateFormat对象
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            //2. 创建Date
            Date date = new Date();
            //格式化date(日期转字符串)
            String str = sdf.format(date);
            System.out.println(str);
            //解析(字符串转时间)
            Date date1 = sdf.parse("2021年02月24日 12:05:42");
            System.out.println(date1);
    
    
        }
    }
    

    8. System

    • System系统类,主要用于获取系统的属性数据和其他操作,构造方法是私有的
    	static void arraycopy(...)	//1.复制数组
    	static long currentTimeMillis();//2.获取当前系统时间,返回的是毫秒值
    	static void gc();//3.建议JVM赶快启动垃圾回收器回收垃圾
    	static void exit(int status);//4.退出JVM,如果参数是0表示正常退出JVM,非0表示异常退出JVM
    
    public class Demo01 {
    
        public static void main(String[] args) {
    
            //1. 数组的复制arraycopy
            //src:源数组
            //srcPos:从哪个位置开始复制0
            //dest:目标数组
            //destPos:目标数组的位置
            //length:复制的长度
            int[] array = new int[]{2,4,6,8,10};
            int[] dest = new int[5];
            System.arraycopy(array,4,dest,2,1);
            for (int d : dest) {
                System.out.println(d);
            }
    
            //2. 获取当前系统时间,返回的是毫秒值currentTimeMillis();
            long start = System.currentTimeMillis();
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < 99999; i++) {
                stringBuilder.append(i);
            }
            System.out.println(stringBuilder);//74 StringBuilder用时0.074秒,速度比String快太多了
    
            long end = System.currentTimeMillis();
            System.out.println("用时:" + (end - start));
    
            //3. 建议JVM赶快启动垃圾回收器回收垃圾gc();
            new Student("a", 20);
            new Student("b", 20);
            new Student("c", 20);
            new Student("d", 20);
            new Student("e", 20);
            //回收垃圾
            System.gc();
            System.out.println("回收垃圾");
    
            //4. 退出JVM exit();
            System.exit(0);
            System.out.println("程序结束了......");
        }
    
    
    }
    
  • 相关阅读:
    练习题
    练习题
    作业 —— day77
    解决:Django项目no such table django_session
    解决:A server error occurred. Please contact the administrator
    作业24
    元类
    类的内置方法
    反射
    考试错题
  • 原文地址:https://www.cnblogs.com/MRASdoubleZ/p/14443192.html
Copyright © 2020-2023  润新知