理解匿名内部类和lambda表达式
创始人
2025-05-31 10:59:57
0

1.概念

我这里理解的来源1.韩顺平老师的30天学java的课件中的概念

一个类的内部又完整的嵌套了另一个类结构,被嵌套的类策划归纳为内部类(inner class),嵌套其他类的类称为外部类(outer Class)。

类的五大成员:属性、方法、构造器、代码块、内部类。

内部类的最大特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。源代码中有大量的内部类。

内部类的分类

定义在外部类局部位置上(比如方法内):

  1. 局部内部类(有类名)
  2. 匿名内部类(没有类名,重点!!!!)

定义在外部类的成员位置上

  1. 成员内部类(没有statc修饰)
  2. 静态内部类(使用static修饰)
class Outer{class Inner {}}
class Other {}

快速入门

package com.xxxx.innerclass;public class InnerClass01 {				 //外部其他类public static void main(String[] args) {}
}class Outer {					 //外部类private int n1 = 100;		//属性public Outer(int n1) {		//构造器this.n1 = n1;}public void m1() {			//方法System.out.println("m1()");}{							//代码块System.out.println("代码块...");}class Inner { 			//内部类, 在 Outer 类的内部}
}

匿名内部类的使用

1.本质还是类
2.内部类
3.该类没有名字
4.同时还是一个对象

匿名内部类通常使用一次,后面不再使用。节省位置。
语法:

new  类或接口(参数列表){类体
};
/**
* 演示匿名内部类的使用
*/
public class sss {public static void main(String[] args) {Outer04 outer04 = new Outer04();outer04.method();}
}
class Outer04 { //外部类private int n1 = 10;//属性public void method() {//方法/*基于接口的匿名内部类老韩解读1.需求: 想使用 IA 接口,并创建对象2.传统方式,是写一个类,实现该接口,并创建对象3.老韩需求是 Tiger/Dog 类只是使用一次,后面再不使用4. 可以使用匿名内部类来简化开发5. tiger 的编译类型 ? IA6. tiger 的运行类型 ? 就是匿名内部类 Outer04$1*//*我们看底层 会分配 类名 Outer04$1class Outer04$1 implements IA {@Overridepublic void cry() {System.out.println("老虎叫唤...");}}*//*7. jdk 底层在创建匿名内部类 Outer04$1,立即马上就创建了 Outer04$1 实例,并且把地址返回给 tiger8. 匿名内部类使用一次,就不能再使用*/IA tiger = new IA() {@Overridepublic void cry() {System.out.println("老虎叫唤...");}};System.out.println("tiger 的运行类型=" + tiger.getClass());tiger.cry();tiger.cry();tiger.cry();
/*   
普通方法这样写 
IA tiger = new Tiger();tiger.cry();*//*演示基于类的匿名内部类分析1. father 编译类型 Father2. father 运行类型 Outer04$23. 底层会创建匿名内部类*//*class Outer04$2 extends Father{@Overridepublic void test() {System.out.println("匿名内部类重写了 test 方法");}}*//*4. 同时也直接返回了 匿名内部类 Outer04$2 的对象5. 注意("jack") 参数列表会传递给 构造器*/Father father = new Father("jack"){@Overridepublic void test() {System.out.println("匿名内部类重写了 test 方法");}};System.out.println("father 对象的运行类型=" + father.getClass());//Outer04$2father.test();
//基于抽象类的匿名内部类Animal animal = new Animal(){@Overridevoid eat() {System.out.println("小狗吃骨头...");}};animal.eat();}
}
interface IA {//接口public void cry();
}
//class Tiger implements IA {
//
// @Override
// public void cry() {
// System.out.println("老虎叫唤...");
// }
//}
//class Dog implements IA{
// @Override
// public void cry() {
// System.out.println("小狗汪汪...");
// }
//}
class Father {//类public Father(String name) {//构造器System.out.println("接收到 name=" + name);}public void test() {//方法}
}
abstract class Animal { //抽象类abstract void eat();}

仔细理解代码应该都可以看懂。注释的代码是先用普通代码写的。
这里我们理解lambda表达式。这里就看清代码中的 Father类,里面有构造方法

package com.lambda;/*** 使用lambda表达式替换Runnable匿名内部类* @author MingChenchen**/
public class RunableTest {/*** 普通的Runnable*/public static void runSomeThing(){Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("I am running");}};new Thread(runnable).start();}/*** 使用lambda后的*/public static void runSomeThingByLambda(){new Thread(() -> System.out.println("I am running")).start();}public static void main(String[] args) {runSomeThing();
//      runSomeThingByLambda();}
}上述代码中:
() -> System.out.println("I am running")就是一个lambda表达式,
可以看出,它是替代了new Runnable(){}这个匿名内部类。

结合上面两段代码,我讲一些我的理解

new Thread(() -> System.out.println("I am running")).start();

这里的这个()中的参数是重写的方法 run() 中的参数

这个就是匿名内部类的参数位置。

/*
也可以直接调用,匿名内部类本身也是返回对象*/class 匿名内部类 extends Person {new Person(){@Overridepublic void hi(){System.out.println("匿名内部类重写了 hi 方法,哈哈...");}@Overridepublic void ok(String str){super.ok(str);}}.ok("jack");
}

2.使用lambda表达式实现Comparator

package com.lambda;import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;public class SortList {//给入一个Listprivate static List list = Arrays.asList("my","name","is","uber","and","uc");/*** 对一个String的list进行排序 - 使用老方法*/public static void oldSort(){//排序Collections.sort(list,new Comparator() {//使用新的排序规则 根据第二个字符进行逆序排@Overridepublic int compare(String a,String b){if (a.charAt(1) <= b.charAt(1)) {return 1;}else{return -1;}}});}/*** 新的排序方法 - 使用lambda表达式实现*/public static void newSort(){//lambda会自动推断出 a,b 的类型Collections.sort(list, (a, b) -> a.charAt(1) < b.charAt(1) ? 1:-1);}public static void main(String[] args) {
//      oldSort();newSort();}
}

记住匿名内部类的用法就是使用一次,那个类如果不再调用方法就不会再使用。,然后lambda就是节省了匿名内部类的书写。

在spring中lambda和stream可以很好的一起使用。
看下面两篇文章:
JAVA8之lambda表达式详解,及stream中的lambda使用
Java 中的双冒号“::”
双冒号“::”就是 Java 中的方法引用(Method references)
方法引用的格式是类名::方法名。一般是用作 Lambda表达式。
http://t.csdn.cn/i37UX

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...