Java基础——内部类

Java基础——内部类

1、定义在另一个类中的类:内部类。

内部类可以通过OuterClass.this来获取外部类的引用,同时外部类可以通过outerObject.new InnerClass(construction parameters)来获得内部类对象。同时,内部类用于外部类所有元素的访问权限,在内部类构造时,编译器会隐式的将外部类的引入传入。

public class DotThis{
	void f(){System.out.println("DotThis.f()");}
	public class Inner{
		public DotThis outer(){
			return DotThis.this;
		}
	}
	// A plain "this" wouldbe Inner's "this"
	public Inner inner(){return new Inner();}
	public static void main(String[] args){
		DotThis dt = new DotThis();
		DotThis.Inner dti = dt.inner();
		dti.outer().f();
	}
}/*Output 
DotThis.f()
*///:~

2、在方法和作用域中的内部类:局部内部类。

局部内部类不仅能够访问包含它们的外部类,还能够访问局部变量。不过被引用的局部变量事实上必须是final的,它们一旦赋值就不能被改变。其原因与下文介绍的lambda表达式的原因类似。

3、匿名内部类:只需要使用一次一个类的对象,就可以不必命名了。

invite(new ArrayList<String>() {{add("Harry"); add("Tony")}});
new Object(){}.getClass().getEnclosingClass()
// gets class of static method, 不过直接使用new Object().getClass().getEnclosingClass() 也能通过吧

而对于只包含一个方法的匿名内部类,通常可以使用lambda表达式更精简的实现。

4、静态内部类(嵌套类):如果只是想把一个类隐藏在另一个类的内部,但又不需要引用外部类的对象,可以将内部类声明为static的。同时,声明在接口中的内部类,自动成为static和public的内部类。

5、lambda表达式

    当需要一个只包含一个方法的类的对象(只需要一个方法,但由于Java面向对象,因此必须针对这个方法构建一个类,再将类对象传入:函数式接口)时,可以使用lambda表达式进行实现。使用lambda表达式的重点是延迟执行(多次,适当的条件、时间和位置)。lambda表达式可以引用使用外围作用域中的变量,不过因为不确定lambda表达式将何时、几次被执行,因此引用值必须为不变量。同时,由于共享作用域,因此lambda表达式同样不能有与外围作用域同名的局部变量。

import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

interface Test{
	void accept(int value);
}

public class LambdaTest {
	static void repeat(int n, Test action){
		for(int i=0; i<n; i++)
			action.accept(i);
	}
	public static void main(String[] args) {
		String[] planets = new String[] {
		    "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"
		};
		System.out.println(Arrays.toString(planets));
		System.out.println("Sorted in dictionary order: ");
		Arrays.sort(planets);
		System.out.println(Arrays.toString(planets));
		System.out.println("Sorted by length: ");
		Arrays.sort(planets, (first, second) -> first.length() - second.length());
		System.out.println(Arrays.toString(planets));
		
		repeat(10, i->System.out.println("Countdown: " + (9 - i)));
		// if the function can be implement directly by current method simply
		repeat(10, System.out::println);
		
		Timer t = new Timer(1000, event -> System.out.println("The time is " + new Date()));
		t.start();

		JOptionPane.showMessageDialog(null, "Quit Program?");
		System.exit(0);
	}
}/* Output 
[Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune]
Sorted in dictionary order: 
[Earth, Jupiter, Mars, Mercury, Neptune, Saturn, Uranus, Venus]
Sorted by length: 
[Mars, Earth, Venus, Saturn, Uranus, Jupiter, Mercury, Neptune]
Countdown: 9
Countdown: 8
Countdown: 7
Countdown: 6
Countdown: 5
Countdown: 4
Countdown: 3
Countdown: 2
Countdown: 1
Countdown: 0
0
1
2
3
4
5
6
7
8
9
The time is Tue May 29 15:54:37 GMT+08:00 2018
The time is Tue May 29 15:54:38 GMT+08:00 2018
The time is Tue May 29 15:54:39 GMT+08:00 2018
*///:~

标准形式:

(String first, String second) -> {
    if(first.length() < second.length()) return -1;
    else if(first.length() > second.length()) return 1;
    else return 0;
}

可推断返回值,同时单行可省略花括号:

(String first, String second) -> first.length() - second.length()

可以推断类型可省略类型:

(first, second) -> first.length() - second.length()

只有一个参数可省略小括号:

first -> first.length()

无参数必须保留小括号:

() -> System.out.println("Hello World!")

现有方法能够直接实现功能:

Math::pow // 等价于 (x, y) -> Math.pow(x, y)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值