内部类
-
定义在外部类内部的一个完整的类—>编译后会生成独立的 . 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繁忙,则暂不回收
final finalize 修饰符、关键字 方法名 可以修饰类(不能继承没有子类)、方法(允许被子类继承不允许覆盖)、变量(作用范围内的常量,只允许一次赋值,可以多次使用) 在垃圾回收器回收垃圾对象时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 超过了字符数组范围 整型byte,short,long缓冲区都是-128~127 浮点型没有缓冲区
-
通常将基本类型的属性定义成包装类型,用于区分有效数据和无效数据(如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”) | |
---|---|---|
一个对象,在串池中 | 两个对象,堆空间一个,串池一个 | |
String | StringBuilder | StringBuffer |
不可变长,一旦创建不能更改 | 可变长字符串 | 可变长字符串 |
在字符串拼接上效率相对较低 | 拼接效率较高 | 拼接效率较高 |
线程安全 | 线程不安全,并发效率较高 | 线程安全,并发效率较低 |