CoreJava Day11

内部类

  • 定义在外部类内部的一个完整的类—>编译后会生成独立的 . class 文件—>外部类类名 $ 内部类类名 . class

    • 内部类可以使用外部类的成员(私有的成员也可以)
  • 内部类分类—>阅读源码需要

    • 成员内部类—>类比实例变量—>定义在类以内,方法以外

      • 成员内部类的对象创建依赖于外部类的对象

        Outer o = new Outer();
        Outer.Inner i = o.new Inner();
        
      • 外部类类名 . this 代表当前外部类对象—>外部类类名 . this . 属性 访问外部类当前对象属性

      • 成员内部类中不能定义静态成员—>静态成员和对象无关,但内部类依赖外部类对象

    • 静态内部类—>类比静态变量—>定义在类以内,方法以外,被static修饰—>阅读源码需要

      • 可以定义静态成员和非静态成员

      • 创建静态内部类对象时,只要依赖于外部类的类名即可

        Outer.Inner i = new Outer.Inner();
        
      • 可以通过类名直接访问静态内部类中的静态成员或成员方法

        Outer.Inner.静态属性名
        Outer.Inner.静态方法名()
        
      • 静态内部类中只能访问外部类的静态成员(静态属性和静态方法)

    • 局部内部类—>类比局部变量—>定义在方法以内—>过度

      • 创建对象需要在定义它的方法内部完成,同时对象的语句需要在局部内部类定义的后面
      • 可以直接访问外部类私有成员
      • 可以访问定义它的方法内部的局部变量,但是JVM一旦检测到局部变量被局部内部类访问,JVM会为局部变量默认添加一个final ( 只能应用,不能更改),此语法被称为语法糖—>jdk7.0以上才有
    • 匿名内部类—>特殊的局部内部类—>应用层:对接口实现类的进一步简化

      • 通常利用匿名内部类完成接口实现类的定义及对象的创建

      • 匿名内部类必须实现一个接口或是继承一个父类

      • 匿名内部类的定义和对象的创建一起完成,而且基于一个匿名内部类只能创建该类的一个对象

        interface IA{
        	void m1();
        }
        //利用匿名内部类完成IA接口的实现类定义及对象的创建
        IA ia = new IA(){		//ia即匿名内部类创建的唯一对象
          public void m1(){
            //方法实现部分
          }
        }
      • Lambda表达式—>对匿名内部类进一步的简化形式 ( 同时接口只能是函数式接口 ) —>JDK8.0新特性

        接口名 引用名 = ( 形参列表 ) -> {	//方法实现部分 }
        
        Lambda完成对接口实现类的定义及对象的创建
        

常用类

Object
  • 位于java.lang包中,是所有类的根类、父类 ( 直接父类或是间接父类 )—>没有写继承关系的JVM默认继承直接父类为Object

  • Object类型的引用可以存储任意类型的对象—>多态

  • Object类中定义的功能方法,是所有类都默认具备的功能

  • Object常用方法

    • getClass()—>无参,被final修饰,不允许子类覆盖,返回Class—>获取引用中实际存储的对象类型

      —>区分instanceof

      • 引用名1.getClass() == 引用名2.getClass() 判断两个引用中存储的对象类型是否一致
    • hashCode()—>无参,没有被final修饰,允许子类覆盖,返回值int—>获取对象的哈希码值

      • 将对象在内存中的十六进制地址转换成十进制的整数结果—>不同对象地址不同,故哈希码值也不同
    • toString()—>无参,没有被final修饰,允许子类覆盖,返回值String—>方便打印输出对象信息

      • Object类中toString方法实现原理:包名 . 类名+“@”+哈希码值十六进制整数
      • 覆盖原则—>将所有属性拼凑为一个String类型的结果,作为返回值返回
    • boolean equals ( Object obj ) —>形参Object类型,没有被final修饰,允许子类覆盖,返回值boolean—>比较对象内容是否相同

      • = = 可以用来比较两个引用地址是否相同
      • Object中的equals比较的是对象地址是否相同,如果想利用equals比较对象内容,需要覆盖Object中的equals—>覆盖从五个方面:形参为Object,自反性、判断形参是否为空、判断两个引用是否为同一类型、强转父类引用、将对象内容一一比较
    • finalize()—>没有被final修饰,允许子类覆盖—>JVM的垃圾回收器在回收垃圾对象时JVM自动调用的方法—>垃圾回收器的策略在进行性能调优时应用

      • 垃圾对象—>没有任何引用指向的对象,统称为垃圾对象

      • 垃圾回收器是JVM内置的,简称GC / gc,用于回收 JVM内存中的垃圾对象

      • 目的:释放JVM内存空间,提高内存利用率

      • GC回收时机:

        • 自动回收机制:当JVM内存满时,JVM启动垃圾回收器将垃圾对象进行一次性的回收—>在回收垃圾对象时,自动调用一次finalize方法—>不是依靠finalize方法回收,注意先后顺序
        • 手动回收机制:利用System.gc(); 通知JVM启动垃圾回收器回收垃圾对象,如果GC空闲,清理垃圾对象;如果GC繁忙,则暂不回收
        finalfinalize
        修饰符、关键字方法名
        可以修饰类(不能继承没有子类)、方法(允许被子类继承不允许覆盖)、变量(作用范围内的常量,只允许一次赋值,可以多次使用)在垃圾回收器回收垃圾对象时JVM自动调用的方法
        可以手动System.gc()通知JVM启动垃圾回收器
包装类
  • 为八种基本数据类型分别定义的八个类被称为包装类—>位于java.lang包中,应用时无需导包
    • 除了int—>Integer char—>Character 其余都是首字母大写-------->关键字—>类名
    • 八种包装类都被final修饰,不能被子类继承
    • int—>Integer
      • 借助Integer构造方法—>Integer i = new Integer(a); //new对象
      • 借助Integer类中静态方法valueOf();—>返回Integer类型—>Integer i = Integer.valueOf(a);
    • Integer—>int
      • 借助Integer类中成员方法intValue();---->int n = i.intValue();
    • String—>Integer
      • 借助Integer类中构造方法—>Integer i = new Integer(“123”);
      • 借助Integer类中静态方法—>Integer i = valueOf(“123”);
    • Integer—>String
      • String s1 = i4.toString(); //借用toString()方法
      • String s = i4 + “”; //借助字符串拼接
    • int—>String
      • String s = 23 + ‘’’; //字符串拼接
    • String—>int
      • int i = Integer.parseInt(“123”); //借助Integer中的静态方法parseInt(),但是字符串中只能有数字,否则编译通过,运行报错—>java.lang.NumberFormatException(数值格式转换异常)
自动装箱和自动拆箱
  • jdk5.0开始,基本数据类型和对应包装类型之间可以自动完成转换,此过程被称为自动装箱和拆箱

    • 装箱—>基本数据类型转换成对应包装类型的过程—>底层采用的是Integer类中的静态方法valueOf完成转换的
    • 拆箱—>包装类型转换为对应基本数据类型的过程
  • 装箱中valueOf方法底层实现原理—>为了提高效率,对Integer进行预先包装处理,预包装数据段为

    -128~127,只要在此数据段内,自动包装都是直接从缓冲区中获取,不重新new对象

    Integer i1 = 128;
    Integer i2 = 128;
    //valueOf底层源码,不在-128~127之间就new一个新的Integer
    //即缓冲区--->预先对一些数据存储,用的时候可以直接使用,提高效率
    System.out.println(i1==i2); //false 超过了字符数组范围
    
    整型byteshortlong缓冲区都是-128127
    浮点型没有缓冲区
    
  • 通常将基本类型的属性定义成包装类型,用于区分有效数据和无效数据(如0和null),注意,包装类之间没有自动类型提升,所以Double类型的必须有小数部分。同时也可以让Object管理所有的数据类型

String类
  • 位于java.lang包中,被final修饰的,不能被继承

  • String s1 = “Hello”---->直接利用“”获取字符串的形式,直接在串池中查看是否定义此串,已经存在则直接使用;如果不存在,只在串池中创建一个字符串对象—>对象个数0~1

  • String s2 = new String(“World”)—>在内存中产生两个对象,一个在堆空间,一个在串池中,如果串池已经存在所定义的字符串,则无需在串池中产生对象,但是至少在堆空间中产生一个对象—>对象个数1~2

    —>也可以利用String中的intern()方法让new出来的改变默认指向,变为指向串池中的字符串对象

String s1 = "hello";		//在串池中,产生一个对象
String s2 = new String("world");	//产生两个对象,一个在堆,一个在串池。s2拿的是堆里的地址

String s3 = "Hello";    //没有产生对象
System.out.println(s1 == s3);    //地址相同

String s4 = "world";    //没有产生对象,且指的是串池中的
System.out.println(s4==s2);     //false 地址不同

String s5 = new String("world");	//只产生了一个堆中的对象

//可以让new的指向串池里面对象,默认指向堆
System.out.println(s2.intern() == s4);//此时s2指向串池
栈空间:局部变量

堆空间:对象

方法区:static等、静态常量 ( 常量池 ) 、字符串 ( 串池 )  

方法区包含--->常量池、串池
  • 字符串—>本质上是char类型的数组—>char[] value;

  • 常用方法

    • ***public char charAt(int n)***—>获取字符串数组中下标为n的字符—>注意越界问题,编译通过,运行报错—>java.lang.StringIndexOutOfBoundsException(字符串下标越界)

    • ***public int length()***—>返回字符串的长度—>区分获取数组长度 . length;

    • ***public boolean contains(String str)***—>判断当前字符串中是否包含str

    • public char[] toCharArray()—>将字符串转换成字符数组

    • ***public boolean equals(String str)***—>判断当前字符串内容和str是否相等,区分大小写

      • public boolean equalsIgnoreCase(String str)—>比较内容时忽略大小写
    • public int indexOf(String str)—>获取str在当前字符串中第一次出现首字符的下标,没有出现返回-1。

    • public int indexOf(String str,int fromindex)---->从指定下标fromindex后面开始找第一次出现str的首字符下标,没有返回-1

    • public int lastIndexOf(String str)---->查找字符串str在当前字符串中最后一次出现的首字符下标

    • public String trim()—>去除字符串前后的空格,字符串中间的空格不管—>配合***Integer.parseInt***做字符串转数值使用

    • public String[] split(String str)—>以str拆分当前字符串,将拆分结果存储在String数组中

    • public String toUpperCase()—>String字母小写转大写

    • public String toLowerCase()—>String字母大写转小写

    • public String concat(String str)—>字符串拼接到尾部,作用等价于 + 号

    • public boolean endsWith(String str)—>判断当前字符串是不是以str结尾

    • public boolean startsWith(String str)—>判断当前字符串是不是以str开头

    • public String replaceAll(String str,String str1)—>str全部变为str1

    • public String substring(int i,int j)—>从 i 下标截取到 j-1 下标

    • public boolean isEmpty()—>判断当前字符串是否为空

  • String不可变性—>字符串字面值为常量,一旦创建不能改变,如果想在字符串上拼接一个新的字符串,先在原有字符串的基础上拷贝一个副文本,在副文本上完成字符串拼接

  • 因为不可变性,所以String类型字符串在完成字符串拼接时,相对拼接效率较低

可变长字符串—>StringBuilder、StringBuffer—>位于java.lang中
  • StringBuilder : JDK5.0—>线程不安全,并发效率相对较高—>被final修饰,不能继承

  • StringBuffer : JDK1.0—>线程安全,并发效率相对较低

  • 常用:

    • StringBuilder() : 无参数的构造方法
    • StringBuilder(String str) : 有参数的构造方法
    • append ( 形参列表 ) :拼接方法—>在可变长的字符串基础上完成字符串的拼接
    • 最后要用toString变成不可变长的字符串进行操作
String s = “hello”String s = new String(“World”)
一个对象,在串池中两个对象,堆空间一个,串池一个
StringStringBuilderStringBuffer
不可变长,一旦创建不能更改可变长字符串可变长字符串
在字符串拼接上效率相对较低拼接效率较高拼接效率较高
线程安全线程不安全,并发效率较高线程安全,并发效率较低
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值