匿名内部类与lambda表达式
匿名内部类
什么是匿名内部类
本质上就是函数,主要是为了在当前类中创建一个接口的实现类或者重写某个父类的方法,而最终产生的对象只在该类中使用,不会被其他类所调用。
使用匿名内部类创建线程对象—runnable
package cn.lizemin.demo.thread;
/**
* @author: lizemin
* @version: 1.0
*/
public class AnonymousDemo {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
//使用匿名内部类创建线程对象
Runnable my = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("我是匿名内部类中的多线程"+i);
}
}
};
Thread my_thread = new Thread(my);
my_thread.start();
for (int i = 0; i < 20; i++) {
System.out.println("主线程--------"+i);
}
}
}
使用匿名内部类创建线程对象—继承thread
package cn.lizemin.demo.thread;
/**
* @author: lizemin
* @version: 1.0
*/
public class AnonymousDemo {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
//使用匿名内部类创建线程对象
/*Runnable my = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("我是匿名内部类中的多线程-------runnable接口方式"+i);
}
}
};*/
//使用匿名内部类创建线程对象
Thread thread = new Thread() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("我是继承thread的匿名内部类"+i);
}
}
};
//Thread my_thread = new Thread(my);
thread.start();
//my_thread.start();
for (int i = 0; i < 20; i++) {
System.out.println("主线程--------"+i);
}
}
}
使用lambda表达式创建线程对象
package cn.lizemin.demo.thread;
/**
* @author: lizemin
* @version: 1.0
*/
public class LambdaDemo {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
//使用lambda表达式创建线程对象
Runnable my = () -> {
for (int i = 0; i < 20; i++) {
System.out.println("我是lambda表达式中的多线程"+i);
}
};
Thread my_thread = new Thread(my);
my_thread.start();
for (int i = 0; i < 20; i++) {
System.out.println("主线程--------"+i);
}
}
}
使用lambda表达式的技巧
- 当代码块只有一个句子的时候,可以省略花括号
- 当参数只有一个的时候,可以省略小括号
- 当代码块只有一个句子,而且有返回值的时候,可以省略return
- 任何情况下都可以省略参数类型,多个参数的情况下,要么都省略参数类型,要么都不省略
内部类的特点
demo演示
创建非静态内部类中的对象。
在内部类中调用外部类的属性和方法。
成员内部类:非静态
package cn.lizemin.demo.thread.innerClass;
import cn.lizemin.TestOuter;
import com.sun.org.apache.bcel.internal.generic.NEW;
import java.sql.SQLOutput;
/**
* @author: lizemin
* @version: 1.0
*/
public class InnerClass {
int age = 10;
public void jump(){
System.out.println("test---jump");
//外部类想要访问内部类的东西,需要创建内部类的对象然后进行调用
Inner inner = new Inner();
System.out.println(inner.age);
}
public class Inner{
int age = 20;
public void test(){
//可以调用外部类的方法
jump();
//5.内部类可以访问外部类的内容
System.out.println(age);//20,输出的是该类中的age,符合就近原则。
System.out.println(InnerClass.this.age);//10, 等价于InnerClass.age
//修改内部类成员变量的值
int age = 30;
//8.内部类和外部类属性重名的时候,如何进行调用, 就近原则:
System.out.println(age);//30
System.out.println(this.age);//20
}
}
}
demo:
package cn.lizemin.demo.thread.innerClass;
/**
1. @author: lizemin
2. @version: 1.0
*/
public class Demo {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
System.out.println(innerClass.age);//10
//创建内部类的对象
InnerClass.Inner inner = innerClass.new Inner();
System.out.println(inner.age); //20
System.out.println("下面是test方法的输出:");
//调用内部类中的方法
inner.test();
}
}
总结
- 如果内部类中的属性和外部类的属性重名的话,没有特别指定,在内部中使用该属性时,默认是用的内部类的属性的值。(就近原则)
- 可以直接调用外部类的方法,需要在内部类的方法中调用外部类的方法
- 在创建非静态内部类的对象前,需要先创建该内部类的外部类的对象
- 外部类想要访问内部类的属性或者方法,需要在方法中创建内部类的对象然后进行调用
成员内部类:静态
package cn.lizemin.demo.thread.innerClass;
/**
* @author: lizemin
* @version: 1.0
*/
public class OuterClass {
int age = 10;
static int money = 20;
public void say(){
System.out.println("test...say");
}
public static void jump(){
System.out.println("test...jump");
InnerStatic innerStatic = new InnerStatic();
//调用静态内部类的属性
System.out.println(innerStatic.age);
}
//静态内部类
static class InnerStatic{
int age = 20;
public void test(){
money = 10;
//静态内部类中只能访问外部类中被static修饰的属性
jump();
System.out.println(money);
}
}
}
package cn.lizemin.demo.thread.innerClass;
/**
* @author: lizemin
* @version: 1.0
*/
public class Demo2 {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
OuterClass.InnerStatic innerStatic = new OuterClass.InnerStatic();
innerStatic.test();
}
}
总结
- 如果创建静态内部类的对象,可以直接创建(需要调用外部类)。
- 静态内部类中只能调用外部类中被static修饰的属性和方法
- 外部类可以直接调用静态内部类中的属性和方法。而不需要创建一个内部类对象。
局部内部类:非静态
package cn.lizemin.demo.thread.innerClass;
import cn.lizemin.demo.thread.blocked.A;
import java.util.Comparator;
/**
* @author: lizemin
* @version: 1.0
*/
public class TestOuter {
int age = 20;
public void sleep(){
System.out.println("test......sleep");
}
public void test(){
int num = 10;
//局部内部类
class InnerLocal{
int money = 20;
public void play(){
//局部内部类中的属性不能在其函数中进行重新赋值。
System.out.println(num);
//可以直接访问外部类的属性
System.out.println(age);
System.out.println(money);
sleep();
}
}
//创建内部类的对象,并调用其内部的方法
InnerLocal innerLocal = new InnerLocal();
innerLocal.play();
}
//匿名内部类
public Comparable test2(){
return new Comparable() {
@Override
public int compareTo(Object o) {
return 20;
}
};
}
}
demo
package cn.lizemin.demo.thread.innerClass;
/**
* @author: lizemin
* @version: 1.0
*/
public class Demo3 {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
TestOuter testOuter = new TestOuter();
testOuter.sleep();
testOuter.test();
}
}
总结:
- 局部内部类无法在外层类的函数中创建对象,因此外部类的函数中不能调用局部类中的方法或者属性。但是可以在局部内部类所在的函数中创建对象,然后通过对象调用其中的方法。
- 局部内部类中的属性不能在其函数中进行重新赋值。其内部的属性相当于是被final给修饰的一个常量。
- 可以直接调用外部类的属性和方法。
- 匿名内部类就是一个局部内部类。
不存在静态的局部内部类
创建成员静态内部类的对象
这里需要注意的是静态内部类的权限是public,否则是可能不能创建的。
package cn.lizemin.demo.thread.outer;
/**
* @author: lizemin
* @version: 1.0
*/
public class Outer {
public static class Inner{
}
}
demo
package cn.lizemin.demo.thread.test;
import cn.lizemin.demo.thread.innerClass.OuterClass;
import cn.lizemin.demo.thread.outer.Outer;
/**
* @author: lizemin
* @version: 1.0
*/
public class Test {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
//注意这种写法
Outer.Inner inner = new Outer.Inner();
}
}