第九章
一.内部类
1.什么是内部类?
放在一个类内部的类称为内部类
2.作用?
提供更好的
封装性
,只能让外部类访问,不允许同一个包类的其他类直接访问
内部类
可
直接访问外部类的私有属性(内部类被当成其外部类的成员)。但外部类
不可
访问内部类的私有属性。
3.使用场合?
由其更好的封装性,在只为所在外部类提供服务的情况下优先使用。
4.分类?
4.1成员内部类(可被修饰)
a)非静态内部类(可看作外部类的一个对象)
b) 静态内部类(可看作外部类的一个静态成员):
不一定存在对应的外部类对象。
4.2匿名内部类
适合那种只用一次的类
5.成员内部类和匿名内部类
成员内部类
1) 在类的成员位置,编写的内部类,称之为成员内部类
2)当外部类和内部类有重名成员时,内部类调用外部类重名成员方式:
<外部类名>.This.<外部类成员名>
Outer.this.a;
3)在别的类文件中,想实例化一个类的内部类的话
一般实例化外部类,然后通过外部类的方法有调用内部类
不过也可以在别的类文件中,实例化一个类的内部类
先导包,然后实例化对象
Inner inn=new Outer().new Inner();(一般不会这样,太麻烦,可以作为知识点来记)
4)在编译后,所有内部类(包括匿名内部类)也会产出自己独立的class文件
5)注意条件:
局部变量和成员变量相比,没有默认值,因此在使用前, 必须声明和赋值
匿名内部类
就是在类中编写的一个通过就地实现父类(接口)而编写的一个没有名字的内部类
实现前提:实现继承或接口(类不用写extends和 implements)
特别需要注意:
匿名内部类的方法中,不能修改该内部类所在方法中局部变量的值且局部变量的值只能赋值一次,即此局部变量的值为final修饰
在使用匿名内部类时,要记住以下几个原则:
匿名内部类的对象是向上造型后的所以只能调用父类的可访问成员(父类有的方法,没有的不能自己创造)
·匿名内部类不能有构造方法。
·匿名内部类不能定义任何静态成员、方法和类。
·匿名内部类不能是public,protected,private,static。
·只能创建匿名内部类的一个实例。(类实例出来就是对象)
·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
匿名类和内部类中的中的this :
当在匿名类中用this时,这个this指的是匿名类或内部类本身。
如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名
例子:
abstract class y{
abstract void eat();
}
class text{
public static void main(String[] args) {
y x=new y() {
void eat() {
System.out.println(“2”);
}
};
x.eat();
}
}
二.String和StringBuilder和StringBuffer
String的优化措施照顾重用性(在堆内存中,有字符串常量池,用于保存所有使用字面量形式创建的字符串对象,当再次使用使用新的字符串会重用,而不创建新的,来节省开销),但会造成内存开销大,运行效率差。(如果字符串对象在字符串常量池中不停被创建,虽然有gc机制会去清理,但不断创建字符串对象也可能导致堆内存溢出。)
由此,便引出 StringBuilder,其内部维护了一个可变的char数组,所有的修改都是在这个数组中进行,因此开销小,性能好,并提供了修改字符串的一系列方法,增删改插。
append增 delete replace改(含头不含尾) insert插
1.运行速度
StringBuilder (可变字符序列)> StringBuffer(可变字符序列) > String(不可变字符序列)
String str=“abc”;
System.out.println(str);
str=str+“de”;
System.out.println(str);
首先创建一个String对象str,并把“abc”赋值给str,然后JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了
Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。
而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。
(String str=“abc”+“de”;//和String str=”abcde”一样,此时String最快,因为没有创建、回收对象这个操作)
2.线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
3. 总结
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
三.包装类
1.什么是包装类?
JAVA是一个面向对象的语言,而基本数据类型不是面向对象的,但我们在实际使用中,经常需要将基本数据类型转化成对象,
比如:集合的操作中,需要将基本数据类型转化成对象。
2.为什么需要包装类?
是为了解决基本类型不能直接面向对象开发的问题
2.对应关系:
包装类在java.lang包。
6个表示数字的包装类继承自java.lang.Number,其他两个继承自Object
3.自动拆箱和自动装箱
自动装箱:基本类型就自动的封装到与它相同类型的包装中,
如:Integer i = 100;
本质上是,编译器为我们们添加了Integer i = new Integer(100);jdk5.0后出现自动装箱。
自动拆箱:包装类对象自动转换成基本类型数据。
如:int a = new Integer(100);
本质上,编译器编译时为我们添加了:int a = new Integer(100).intValue();
Integer d = 1234;
Integer d2 = 1234;
System.out.println(d == d2);//false
System.out.println(d.equals(d2));//true
Integer d3 = 123;
Integer d4 = 123;
System.out.println(d3==d4);//true [-128,127]之间的数,仍然当作基本数据类型来处理。作业:提高运算效率
System.out.println(d3.equals(d4));//true
四.时间处理相关类