我这里理解的来源1.韩顺平老师的30天学java的课件中的概念
一个类的内部又完整的嵌套了另一个类结构,被嵌套的类策划归纳为内部类(inner class),嵌套其他类的类称为外部类(outer Class)。
类的五大成员:属性、方法、构造器、代码块、内部类。
内部类的最大特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。源代码中有大量的内部类。
定义在外部类局部位置上(比如方法内):
- 局部内部类(有类名)
- 匿名内部类(没有类名,重点!!!!)
定义在外部类的成员位置上
- 成员内部类(没有statc修饰)
- 静态内部类(使用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