一、java学习 | 内部类和常用类【8】

静态访问非静态 ,非静态必须实例化

1.内部类
分为四种形式:
①成员内部类;
②静态内部类static;
③局部内部类:定义在方法内部;
④匿名内部类:无名内部类,比如在某个方法下面不命名new一个对象;

概念:在一个类的内部再定义一个类
特点:编译后可生成独立的字节码文件 :)见下方图
内部类可以直接访问外部类的私有成员,而不破坏封装
可以为外部类提供必要的内部功能组件
字节码文件
①成员内部类;
在类的内部定义,与实例变量、实例方法同级别的类
它创建时依赖于外部类对象

        // 创建外部类对象
        Outer o1 = new Outer();
        // 创建内部类对象
        Inner i1 = o1.new Inner();
        // 一步到位
        Inner i2 = new Outer().new Inner();

*当外部类与内部类有重名属性时,优先访问内部类

 // 打印外部属性 // 内部类属性与外部类属性名相同,必须Outer.this.
            System.out.println(Outer.this.name);
            System.out.println(Outer.this.age);
            
            // 打印内部类属性
            System.out.println(this.name);
            System.out.println(this.address);
            System.out.println(this.phone);

成员内部类不能定义静态成员,但可以定义静态常量

②静态内部类static;
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
只有内部类才可以用static修饰

package com.common.member;

public class Outer {
    private String name = "chenhao";
    private int age = 8;

    // 静态内部类 它的级别与外部类相同
    static class Inner{
        private String address = "shanghai";
        private String phone = "111";
        // 静态成员
        private static int count = 1000;

        public void show(){
            // 调用外部类的属性
            System.out.println(new Outer().name);
            System.out.println(new Outer().age);
            // 调用静态内部类的属性和方法
            System.out.println(address);
            System.out.println(phone);
            // 调用静态内部类的静态属性
            System.out.println(Inner.count);
        }
    }
}
// 如何去调用呢
package com.common.member;

public class TestOuter {
    public static void main(String[] args) {
        // 直接创建静态类对象
        Outer.Inner I1 = new Outer.Inner();
        // 调用方法
        I1.show();
    }
}

③局部内部类;
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法内(所以实例化时必须在方法内执行)
方法中若有局部变量,为了适应内部类,必然会有一个隐藏的final(jdk1.8以上),避免方法执行完,变量消失,导致局部内部类无法访问该变量。

package com.common.local;


public class Outer {
    private String name = "chenhao";
    private int age = 35;

    public void show(){
        // 定义局部变量 注意不能加任何访问修饰符
        // 实际上这里是有一个隐藏的final 避免方法执行完,变量消失,导致局部内部类无法访问该变量
        String address = "shenzhen";

        // 局部内部类 注意不能加任何访问修饰符
        class Inner{
            // 属性
            private String phone = "114514";
            private String email = "244@163.com";

            public void show2(){
                // 访问外部类属性
                System.out.println(Outer.this.name);
                System.out.println(Outer.this.age);
                // 访问内部类属性
                System.out.println(phone);
                System.out.println(email);
                // 访问局部变量 jdk1.7 要加final jdk1.8 默认隐藏final;
                // 所以不能修改这个变量
                System.out.println(address);
            }
        }
        // 创建局部内部类对象
        Inner i1 = new Inner();
        i1.show2();

    }

}

// 如何调用
package com.common.local;

public class TestOuter {
    public static void main(String[] args) {
        Outer o1 = new Outer();
        o1.show();
    }
}

限制了类的使用范围
④匿名内部类
没有类名的局部内部类(特征一切与局部内部类相同)
必须继承一个父类或者实现一个接口

package com.common.anonymous;

// 接口
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 Usb(){
		            @Override
		            public void service() {
		                System.out.println("连接电脑成功, 风扇开始工作...");
		            }};
        usb.service();
  };

定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
优点:减少代码量 缺点:可读性较差
匿名内部类出现后,字节码文件目录会出现一个自动命名的文件

2.Object类
java继承树的顶端-object
它是所有人的父类,或者间接的父类
所属方法
1getClass(){} 返回引用中存储的实际对象类型 用法:通常用于判断两个类是否一致
2hashCode(){} 返回该对象的hash值 int类型 用法:一般情况,相同对象返回相同的hash值
3toString(){} 返回该对象的字符串形式 用法:展示对象的各个属性值
我们一般都重写,符合我们的想法
4equals(Object obj){} 返回一个布尔值 用法:比较两个对象的地址是否相同
可以进行重写,改写比较规则
5finalize() 自动方法 被判定为垃圾对象时,JVM会自动调用,标记垃圾对象
垃圾对象:没有有效引用指向这个对象
垃圾回收:。。。
自动回收:JVM内存耗尽,一次性回收所有垃圾对象
手动回收:使用System.gc();通知JVM执行垃圾回收
3.包装类
a.基本数据类型对应的引用数据类型,
被包装后就可以使用方法了
基本数据类型存在栈里
而被引用的数据类型存在堆里

基本数据类型包装类型
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean
charCharacter

b.类型转换 拆箱和装箱
装箱:把基本类型转成引用类型,其实就是实例化一个对象
拆箱:把引用类型转成基本类型,将对象里的属性值拿出来

c.基本类型和字符串的转换
toString() 与 parseXXX()
特别注意:boolean中 “true” --> true 非"true"–>false

d.整数缓冲区–堆
java 内置了一个从(-128~127)的整数缓冲区
在自动装箱和拆箱时,都会去调这个整数缓冲区
为什么这么做?
因为这些值经常被使用,所以可以节省内存消耗

4.String
字符串是常量,创建后不可改变
字面值是存在字符串池中的,可以共享(栈,堆,方法区)
jdk1.7前,是在方法区里,1.7后改到堆里了

        String name = "hello"; // 存储在字符串池里
        name = "chenhao"; // 赋了新的值,没有修改数据,而是开辟了新的空间,原来的就成为垃圾
        String name2 = "chenhao"; // 若发现池子里有这个内容,那么就会将栈的变量指向它。
        // 所以 变量 name和name2里存的地址是一样的。
        System.out.println("-----------------------------------------");
        // 另一种创建字符串的方式
        String str1 = new String("java"); // 堆里和方法区里都有内容。先指向堆,堆再指向池。实际内存里只会有一个,在池里。
        String str2 = new String("java");
        System.out.println(str1.equals(str2));

常用方法:

package com.common.string0;

import java.util.Arrays;

public class str0 {
    public static void main(String[] args) {
        String name = "hello"; // 存储在字符串池里
        name = "chenhao"; // 赋了新的值,没有修改数据,而是开辟了新的空间,原来的就成为垃圾
        String name2 = "chenhao"; // 若发现池子里有这个内容,那么就会将栈的变量指向它。
        // 所以 变量 name和name2里存的地址是一样的。
        System.out.println("--------------------字符串存储---------------------");
        // 另一种创建字符串的方式
        String str1 = new String("java"); // 堆里和方法区里都有内容。先指向堆,堆再指向池。实际内存里只会有一个,在池里。
        String str2 = new String("java");
        System.out.println(str1.equals(str2));

        System.out.println("---------------------1字符串方法使用--------------------");

        //1、length() 返回字符串长度
        //2、charAt(int index) 返回某个位置的字符
        //3、contains(String str) 判断是否包含某个字符串

        String content = "chenyanbin";
        System.out.println(content.length());
        System.out.println(content.charAt(content.length()-1));
        System.out.println(content.contains("chen"));
        System.out.println(content.contains("yan"));

        System.out.println("---------------------2字符串方法使用--------------------");

        //4、toCharArray() 字符串转为数组
        //5、indexOf(String str) 查找str首次出现下标索引, 若存在返回, 不存在返回-1
        //6、lastIndexOf(String str) 查找str最后一次出现的下标索引

        String content2 = "wuzhicheng wuzhicheng wuzhicheng";
        System.out.println(Arrays.toString(content.toCharArray()));
        System.out.println(content2.indexOf("wu"));
        System.out.println(content2.indexOf("wu",2));
        System.out.println(content2.lastIndexOf("wu"));

        System.out.println("---------------------3字符串方法使用--------------------");

        //7、trim() 去掉字符串前后的空格
        //8、toUpperCase() 小写转大写  toLowerCase() 大写转小写
        //9、endWith(String str) 判断字符串是否以str为结尾 返回boolean值 同理也有startWith(String str)

        String content3 = " Dong JinWei  ";
        System.out.println(content3.trim());
        System.out.println(content3.toUpperCase());
        System.out.println(content3.toLowerCase());
        System.out.println(content3.trim().endsWith("ei"));
        System.out.println(content3.trim().startsWith("Do"));

        System.out.println("---------------------4字符串方法使用--------------------");
        //10、replace(char oldchar, char newchar) // 旧字符串转成新字符串
        //11、split(String str) 对str做一个拆分

        String content4 = "java is best   programming language of the world. I love java";
        System.out.println(content4.replace("java", "php"));

        //String[] arr = content4.split(" "); //
        //String[] arr = content4.split("[ ,]"); //用[] 表示里面的每个字符都会被用来分隔
        String[] arr = content4.split("[ ,]+"); //用[]+ 表示里面的每个字符的连续多个都被视作一个 例如,,,
        System.out.println(arr.length);
        for(String stri : arr){
            System.out.println(stri);
        }

        System.out.println("---------------------4.5字符串方法使用--------------------");
        //12、equals(String str) 是否相等
        //13、compareTo(String str) 比较对应下标字符串在 字典表里的位置 谁大谁小 并返回差值
        //(只比较第1个,第1个相等则往后比较)(中文也可以)
        String n1 = "hello";
        String n2 = "HELLO";
        System.out.println(n1.equals(n2));
        System.out.println(n1.equalsIgnoreCase(n2)); // 忽略大小写比较

        String n3 = "abc"; // a为97
        String n4 = "xyz"; // x为120
        System.out.println(n3.compareTo(n4));

        String n5 = "abc"; //
        String n6 = "abcxyz"; // 这种情况下, 完全相同的部分比完了, 那么比较字符串长度
        System.out.println(n5.compareTo(n6));
    }
}

String案例演示

package com.common.string0;

public class TestStrRepair {
    public static void main(String[] args) {
        StrRepair strRepair = new StrRepair("this is a text");
        System.out.println(strRepair.getContent()); // 输出内容
        // 1.单独获取str里的内容
        String[] arr_str = strRepair.getStrAlone();
        for (String s : arr_str) {
            System.out.println(s);
        }

        // 2.将text替换为pratice
        System.out.println(strRepair.replaceStr("text", "practice"));

        // 3.在text前插入一个easy
        System.out.println(strRepair.replaceStr("text", "easy text"));

        // 4.将每个单词首字母改为大写
        System.out.println(strRepair.getUpperCaseOfFirst(arr_str));
    }
}


package com.common.string0;

public class StrRepair {
    private String str0 = "";
    public StrRepair(String str){
        this.str0 = str; // 构造函数
    }

    public String[] getStrAlone(){
        // 将str中的单词单独获取出来, 可根据下标访问
        String[] arr = this.str0.split("[ ]+");
        return arr;
    }

    public String replaceStr(String old_str, String new_str){
        // 替换旧的字符串为新的
        return this.str0.replace(old_str, new_str);
    }

//    public String insertStr(String ins_str, String ins_index){
//        // 插入字符串到指定位置
//        return this.str0.replace()
//    }

    public String getUpperCaseOfFirst(String[] arr_str){
        // arr_str 中的每个单词首字母改为大写
        String te_str = "";
        for(String stri : arr_str){
            Character temp_str = stri.charAt(0); // 提取首字母
            stri.replace(temp_str.toString(), temp_str.toString().toUpperCase()); // 替换成大写形式
            te_str += stri+" ";
        }
        te_str = te_str.trim();
        return te_str;
    }


    public String getContent(){
        // 返回值
        return this.str0;
    }

    public int getLength(){
        return this.str0.length();
    }


}

可变字符串:

package com.common.string0;

public class VariableStr {
    // 可变字符串
    // JDK1.0 StringBuffer 缓冲区内操作 运行效率相对Builder慢, 比string快 线程安全
    // JDK5.0 StringBuilder 运行效率快, 线程不安全
    // 两者方法一致 尽量用StringBuilder

    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        //1.append 追加
        System.out.println("----------------append 追加----------------");
        sb.append("java 1st");
        System.out.println(sb.toString());
        sb.append(", java nice");
        System.out.println(sb.toString());
        sb.append(", java good");
        System.out.println(sb.toString());

        //2.insert 插入添加
        System.out.println("----------------insert 插入添加----------------");
        sb.insert(0, "I am front, ");
        System.out.println(sb.toString());

        //3.replace 替换 不同:可以替换指定位置
        System.out.println("----------------replace 替换----------------");
        sb.replace(0,4,"hello");
        System.out.println(sb.toString());

        //4.delete 删除 可以删除指定位置
        System.out.println("----------------delete 删除----------------");
        sb.delete(0, 6);
        System.out.println(sb.toString());

        // 清空
        sb.delete(0, sb.length());
        System.out.println(sb.length());

    }

}

5.BigDecimal类
位于java.math包中
作用是精确计算浮点数

方法加减乘除

package com.common.bigdm;

import java.math.BigDecimal;

public class Demo0 {
    public static void main(String[] args) {
        // double 存的是近似值 会导致误差 但在精度较高的情况下不允许
        double d1 = 1.0;
        double d2 = 0.9;
        System.out.println(d1-d2);
        System.out.println("------------------BigDecimal类------------------");
        // 所以需要 BigDecimal类 大浮点数精确计算
        // 一定要用字符串
        BigDecimal bd1 = new BigDecimal("1.0");
        BigDecimal bd2 = new BigDecimal("0.9");

        // 减法
        BigDecimal r1 = bd1.subtract(bd2);
        System.out.println(r1);

        // 加法
        BigDecimal r2 = bd2.add(bd1);
        System.out.println(r2);

        // 乘法
        BigDecimal r3 = bd2.multiply(bd1);
        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 r5 = new BigDecimal("10")
                .divide(new BigDecimal("3"),2,BigDecimal.ROUND_HALF_UP); // Round_Half_up四舍五入
        System.out.println(r5);
    }
}

6.时间类型
Date类

package com.common.timing;

import java.util.Date;

public class Date0 {
    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()-60*60*24*1000); //ms计时
        System.out.println(date2.toLocaleString());
        // 2 after before 判断日期是否在前或后
        boolean b1 = date1.after(date2);
        System.out.println(b1);

        // 比较 compareTo(); 毫秒值相减, 有正负
        int d = date1.compareTo(date2);
        System.out.println(d);

        // 判断是否相等 equals();
        boolean e = date1.equals(date2);
        System.out.println(e);

    }
}

Calendar

package com.common.timing;

import java.util.Calendar;

public class Calendar0 {
    public static void main(String[] args) {

        // Calendar 是protected 提供了获取或设置各种日历字段的方法
        // 1 创建一个对象
        Calendar cal1 = Calendar.getInstance(); //
        System.out.println(cal1.getTime().toLocaleString());
        System.out.println(cal1.getTimeInMillis()); //获取从基准时间到现在的毫秒值

        // 2 获取时间信息
        // 获取各种时间信息
        // 年
        int year = cal1.get(Calendar.YEAR);
        // 月
        int month = cal1.get(Calendar.MONTH);
        // 日
        int day = cal1.get(Calendar.DAY_OF_MONTH);
        // 小时
        int hour = cal1.get(Calendar.HOUR_OF_DAY); // HOUR 12小时进制; HOUR_OF_DAY 24小时进制
        // 分钟
        int minute = cal1.get(Calendar.MINUTE);
        // 秒
        int second = cal1.get(Calendar.SECOND);
        System.out.println(year+"年"+(month+1)+"月"+day+"日"+hour+"时"+minute+"分"+second+"秒");
        // 3 set方法修改时间
        Calendar cal2 = Calendar.getInstance();
        cal2.set(Calendar.DAY_OF_MONTH, 5); // 修改日
        System.out.println(cal2.getTime().toLocaleString());

        // 4 add方法修改时间
        cal2.add(Calendar.HOUR, 1);
        System.out.println(cal2.getTime().toLocaleString());

        // 5 补充方法
        cal2.add(Calendar.MONTH,1);
        int max = cal2.getActualMaximum(Calendar.DAY_OF_MONTH);
        int min = cal2.getActualMinimum(Calendar.DAY_OF_MONTH);
        System.out.println(max);
        System.out.println(min);


    }
}

SimpleDateFormat
可以根据语言环境来格式化和解析日期的具体类
即 进行格式化和解析 日期->文本;文本->日期

package com.common.timing;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormat0 {
    public static void main(String[] args) throws ParseException {
        // 1 创建SimpleDateFormat 对象
        // y->year; M->month;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH-mm-ss");

        // 2 创建Date
        Date date = new Date();
        // 格式化date 日期->文本
        String str_time = sdf.format(date);
        System.out.println(str_time);

        // 解析 文本->日期

        Date date2 = sdf.parse("1990/05/04");

        System.out.println(date2);

    }
}

System类
私有 不用创建对象 直接调用

package com.common.system0;

public class Demo0 {
    public static void main(String[] args) {
        // 1 arraycopy: 数组复制
        // src: 源数组;
        // srcPos: 从哪个位置开始复制;
        // dest: 目标数组
        // destPos: 复制到哪个位置;
        // length: 复制的长度
        int[] src_arr = {18,45,26,76,34,2,103};
        int[] des_arr = new int[8];
        System.arraycopy(src_arr, 0, des_arr, 0, src_arr.length);

        for (int j : des_arr) {
            System.out.println(j);
        }
        /* 对比python的for循环加强写法
        for i in des_arr:
            print(i)
         */

        // 2 可用于时间计算
        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)+"s");

        // 3 System.gc(); 通知垃圾回收器 准备回收
        new Student("aaa",10);
        new Student("bbb",11);
        new Student("ccc",12);

        new Student("ddd",13);

        System.gc();

        // 4 退出JVM 可提前
        System.exit(0);
        System.out.println("程序已经结束了");

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值