zoukankan      html  css  js  c++  java
  • JAVA_匿名内部类

    map是我们常用的对象,对应map的初始化,正常来说,是需要以下这写法的。

    // 正常map初始化
    Map<String,Integer> mapTest01 = new HashMap<String,Integer>();
    mapTest01.put("张三",100);
    mapTest01.put("李四",50);
    mapTest01.put("王五",70);
    System.out.println(mapTest01.toString());
    // 结果:{李四=50, 张三=100, 王五=70}
    

    但是,创建map并立即初始化的话,可以使用以下方法:

    Map<String,Integer> mapTest02 = new HashMap<String,Integer>(){{
        put("张三",100);
        put("李四",50);
        put("王五",70);
    }};
    System.out.println(mapTest02.toString());
    // 结果:{李四=50, 张三=100, 王五=70}
    

    在new后边加了{},这种写法,在写简单线程的时候应该也有用到吧?

    // 简单的线程
    new Thread(){
        @Override
        public void run(){
            for (int i =0; i < 3; i++){
                System.out.println("Thread执行" + i);
            }
        }
    }.start();
    System.out.println("Thread开始");
    // 结果:
    // Thread开始
    // Thread执行0
    // Thread执行1
    // Thread执行2
    

    这,就是匿名内部类的写法。写法格式如下:

    new 父类构造器(参数列表)|实现接口()    
    {    
     //匿名内部类的类体部分    
    }  
    

    简单的说,使用目的是创建,或者说new出一个对象;new之后跟着的,是要继承的父类或者实现的接口;内部类创建实例后马上被使用,或保存,或者像上边的简单线程一样,自己执行。

    OK,匿名内部类是知道了,总之就是new xxx()之后,加个{}嘛~
    那么,map初始化的HashMap<String,Integer>(){{......}};中的{{}}是什么?构造?不,是在对象创建时,用于给成员变量进行初始化的构造代码块

    匿名内部类由于是在使用时才创建的,所以所有静态static相关的东西都
    都无法使用:

    Map<String,Integer> mapTest03 = new HashMap<String,Integer>(){
        static String name = "王五"; //  static语句出现编译异常:Inner classes cannot have static declarations
        {
            put("张三",100);
        }
    };
    

    另外,我们使用map初始化的话,比如统计个值,然后分组放到map里什么的,就可能想先定义一个变量,然后保存进去,如下:

    String strName = "张三";
    Integer score = 100;
    Map<String,Integer> mapTest04 = new HashMap<String,Integer>(){{
        put(strName,score);
    }};
    

    这时候还是很正常的,但是以下语句却不行了。

    // 匿名内部类,的参数使用
    String strName = "张三";
    Integer score = 100;
    score = 40;
    Map<String,Integer> mapTest05 = new HashMap<String,Integer>(){{
        strName = "李四";    // strName语句出现编译异常:Variable 'strName' is accessed from within inner class, needs to be final or effectively final
        put(strName,score); // score语句出现编译异常:Variable 'score' is accessed from within inner class, needs to be final or effectively final
    }};
    

    匿名内部类的变量需要final?这是为什么呢?
    从编译器的角度来说,java的匿名内类实际上还是创建了对应的[.class]文件,有对应的类,而匿名内部类中的外部变量,不是直接使用的外部变量,而是先构造传入,然后使用的。这其中又涉及到参数问题,所以java为了防止混淆,规定了匿名内部类要用final,阻止在匿名内部类内部,改变外部变量的值。
    我的测试类java文件名为【testOf_JAVA_anonymousInternal.java】,编译后,除了本身的.class文件以外,匿名内部来也依次,生成了附加$X的class文件,比如上边mapTest04的例子,匿名内部类是第三个,于是【testOf_JAVA_anonymousInternal$3.class】的内容如下:

    final class testOf_JAVA_anonymousInternal$3
      extends HashMap<String, Integer>
    {
      testOf_JAVA_anonymousInternal$3(String paramString, Integer paramInteger){
        put(this.val$strName, this.val$score);
      }
    }
  • 相关阅读:
    【题解】[USACO07OPEN]Dining G
    【学习笔记】拉格朗日插值
    【题解】简单的数学题
    docker-compose编排参数详解
    Harbor搭建企业级docker仓库
    centos7制作U盘启动盘
    c语言输入矩阵的对角线之和
    搭建rsync+inotify实现实时备份
    CentOS7添加自定义脚本服务
    Linux搭建NFS服务
  • 原文地址:https://www.cnblogs.com/changfanchangle/p/8854799.html
Copyright © 2011-2022 走看看