基础知识
- 内部类
- 关于内部类的说法, 错误的是
a. 内部类不能有自己的成员方法和成员变量
b. 内部类可用abstract 修饰定义为抽象类,也可以用private 或protected 定义
c. 内部类可作为其他类的成员,而且可访问它所在类的成员
d. 除static 内部类外,不能在类内声明static 成员
/*
* 内部类分为四种情况:
* 1:成员内部类
* 2:静态内部类
* 3:匿名内部类
* 4:局部内部类(不常用)
* */
1.成员内部类(普通类)
class OutClass {
private int num = 3;
class Inner {
int num = 4;
void show() {
int num = 5;
System.out.println("num:" + num); // num:5
System.out.println("num:" + this.num); // num:4
// 内部类直接访问外部类中成员
System.out.println("num:" + OutClass.this.num);// num:3
}
}
}
public class InnerClassDemo01 {
public static void main(String[] args) {
// 创建和使用内部类的语法, 如果inner的 private则不能在外部访问
OutClass.Inner inner = new OutClass().new Inner();
inner.show();
}
}
2.静态内部类
class OutClass02 {
private static int num = 3;
// 内部类如果有static方法,则本身必须声明为static方式
static class Inner {
int num=4;
void show() {
System.out.println("show() num:" + num);
}
static void show2() {
System.out.println("show2() num:" + OutClass02.num);
}
}
}
public class InnerClassDemo02 {
public static void main(String[] args) {
// 内部类是static的创建方式
OutClass02.Inner inner=new OutClass02.Inner();
inner.show();
// 内部类与function都是static的情况
OutClass02.Inner.show2();
}
}
静态属性可以直接使用.的方式来调用
3.匿名内部类
最常使用的一种
/*
* 匿名内部类
* */
public class InnerClassDemo03 {
public static void main(String[] args) {
//String[] names = new File("C:/test").list();拿到当前文件夹所有的文件名称
//目的:像过滤指定文件
//String[] names = new File("C:/test").list(new FilenameFilter())文件名的过滤器
//FilenameFilter接口中只有accept方法
String[] names = new File("C:/test").list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// System.out.println("dir:" + dir);
// System.out.println("name:" + name);
return name.endsWith(".jar");
}
});
for(String temp:names){
System.out.println(temp);
}
}
}
4.局部内部类(在某个方法内定义的内部类) 只有该方法被调用的时候,该内部类才会被使用
class OuterClass03 {
int num = 3;
public Object method() {
// 内部类在局部位置上,只能访问被final修饰的局部变量
final int num = 9;
class Inner {
public void show() {
// num 必须设置为final类型
System.out.println("show...." + num);
System.out.println("show...." + OuterClass03.this.num);
}
}
// 如果 num 不加 final类型,则意味着返回的对象调用show的时候 show里面的x已经释放了
Inner inner = new Inner();
inner.show();
return inner;
}
}
public class InnerClassDemo04 {
public static void main(String[] args) {
OuterClass03 out = new OuterClass03();
Object method = out.method();
}
}
内部类可以用abstract 类型或者protected等访问修饰符来修饰
内部类可作为其他类的成员,而且可访问它所在类的成员
除static 内部类外,不能在类内声明static 成员(普通类不可以声明static 成员)
内部类中,静态方法只能定义在静态内部类中
- 内部类使用场景
成员内部类使用
/*
* 成员内部类的使用
* */
public class InnerUserTest01 {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
List<Object> list2=new LinkedList<Object>();
list.iterator();
list2.iterator();
}
}
所有的集合类元素都实现了iterator方法
静态内部类
局部内部类
有时候两个接口中所显示的方法名相同,当一个类相同时实现这两个接口时会出现矛盾,并只可以实现一个重名的方法
成员内部类可以很好的解决这个问题
但是如果外部类的一个变量只想让它在不同的方法内部使用,把变量申明成为局部变量
同理,如果实现的method方法指在内部类使用,则只需要在内部方法中创建内部类 –局部内部类
局部内部类中要使用外面的局部变量,则变量必须采用final关键字
解释:如果外面的局部变量不为final 类型,很可能该方法返回内部类对象的时候,该方法已退出,不为final 类型的成员变量已经被销毁 出栈 ,但是用到该内部对象用到了这个变量,所以返回的内部类对象会报错
/*
* 列举局部内部类的使用场景
* */
public class InnerUserTest02 {
public Object demo01() {
final int num = 1;
// 局部内部类中要使用外面的局部变量,则变量必须采用final关键字
class Inner1 implements Interface01 {
@Override
public int method() {
return num + 1;
}
}
return new Inner1();
}
public int demo02() {
final int num = 1;
class Inner1 implements Interface02 {
@Override
public int method() {
return num * 1;
}
}
int result = new Inner1().method();
return result;
}
public static void main(String[] args) {
InnerUserTest02 test = new InnerUserTest02();
System.out.println(test.demo01());
System.out.println(test.demo02());
}
- 内部类优化单例模式
基本单例模式
// 单例饿汉模式: 调用其它方法时,对象也会被创建
public class SingletonDemo01 {
private static SingletonDemo01 demo;
private SingletonDemo01() {
}
static {
System.out.println("----static---");
demo = new SingletonDemo01();
}
public static SingletonDemo01 getInstance() {
return demo;
}
//调用其他方法时对象也会被创建
public static void otherMethod(){
System.out.println("--------otherMethod---------");
}
public static void main(String[] args) {
SingletonDemo01.otherMethod();
}
}
懒汉模式单例 每次判断,性能方面是不很好
public class SingletonDemo02 {
private SingletonDemo02(){}
private static SingletonDemo02 demo;
public static SingletonDemo02 getInstance() {
if (demo == null) { // 每次要进行判断代码不优雅
synchronized (SingletonDemo02.class) {
if (demo == null) {
demo = new SingletonDemo02();
}
}
}
return demo;
}
}
静态内部类实现单例 -核心
public class SingletonDemo03 {
private SingletonDemo03() {
System.out.println("SingletonDemo03 is create");
}
// 静态内部类,用来实现真正单例
private static class SingletonHolder {
private static SingletonDemo03 instance = new SingletonDemo03();
}
// 通过此方法获取实例
public static SingletonDemo03 getInstance(){
return SingletonHolder.instance;
}
public static void otherMethod(){
System.out.println("-----调用其他方法并不会产生对象------");
}
public static void main(String[] args) {
// SingletonDemo03.otherMethod();
System.out.println(SingletonDemo03.getInstance());
System.out.println(SingletonDemo03.getInstance());
}
}