白白笔记-lambda表达式&内部类

文档:lambda表达式&内部类.note
链接:http://note.youdao.com/noteshare?id=686820bc4907b59c95cb08114caf1e7a&sub=D71C03E7B6D845DDB1C6CFE69EB1E4E8

一、代码块

1.1、静态代码块
说明
使用static修饰的一段用{}包裹起来Java代码段
与成员变量同级
在类加载时执行

static{
  Java代码块
}

1.2、成员代码块
说明
在类的成员中添加代码块,不能使用权限修饰符
在构造方法执行前执行
执行结束后销毁

修饰符 class 类名{
      //其他类成员
   //成员代码
   {
    //Java代码  
    }
}

1.4、本地代码块
说明
将代码块定义在方法中
在括号所在的区域产生一个作用域

方法(){
   //代码
   //成员代码
   {
      //Java代码
   }
   //代码
}

二、内部类

2.1、静态内部类
说明
一个定义在其他类型内部的类型称为内部类
使用static修饰符修饰内部类
静态内部类可以使用所有的权限修饰符
当外部有权限使用时,外部类对于使用者充当包的作用
当在内部类创建类型时,外部类可以省略

权限修饰符 class 外部类{
     .....
     权限修饰符 static class 内部类{
      ....
      }
}

内部类 对象名= new 外部类.内部类构造方法();

示例

public class DemoStaticInnerClass {
	
	/**
	 * 静态内部类
	 */
	public static class Student{
		private long id;
		private String name;
		public void setId(Long id) {
			this.id = id;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		@Override
		public String toString() {
			return "Student [id=" + id + ", name=" + name + "]";
		}
		public Student(Long id, String name) {
			this.id = id;
			this.name = name;
		}
		
		public static void main(String[] args) {
			Student student = new Student(1L,"大黄");
			System.out.println(student);
		}
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//使用静态内部类  内部类 对象名= new 外部类.内部类构造方法();
		DemoStaticInnerClass.Student stu=new DemoStaticInnerClass.Student((long) 1, "李三");
		System.out.println(stu);
	}

2.2、成员内部类
说明
不使用static修饰的内部类。
只有在对象创建之后,类型才会存在
成员内部类可以使用所有的权限修饰符
成员内部类可以直接调用外部类的其他成员
成员内部类对象必须在外部类对象创建后创建
成员内部类在外部对象创建时创建,对象销毁后销毁
成员内部类中this关键字主要表达成员内部类,可以通过
外部类.this的方式表示外部类对象引用

权限修饰符 class 外部类{
      ....
      权限修饰符 class 内部类{
         .....
      }
      .....
}
内部类 对象名= 外部类对象.new 内部类构造方法();
内部类 对象名= new 外部类构造方法.new.内部类构造方法();

示例

public class DemoInnerClass {
	private String name="yang";
	/**
	 * 私有成员内部类
	 * @author dawulei
	 *
	 */
	private class Student{
		private String name="海洋";
		public void print(){
			String line="外部姓名"+DemoInnerClass.this.name+
					"内部姓名"+this.name;
		}
	}
	public Student buildStudent() {
		return this.new Student();
	}
	/**
	 * 共有成员内部类
	 */
	public class Teacher{
		private long id;
		private String name;
		public void setId(Long id) {
			this.id = id;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
	}
}



public class UseInnerClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
	
		System.out.println(new DemoInnerClass().buildStudent());
		//获得外部类对象才能构造内部类对象
		Teacher theacher = new DemoInnerClass().new Teacher();
		//输出
		System.out.println(theacher);
	}

}

2.3、本地类
说明
将类型定义在方法中
类型的声明周期从类的定义时期,一直到类型所在的大括号结束位置,与变量声明周期一直

权限修饰符 class 外部类{
      方法(){
         class 类名{
            .....
         }
      }
}

2.4、匿名内部类
说明
没有名称的类型定义
匿名内部类所在需要创建接口实现类对象或者子类对象,但不希望书写类型实现接口或实现父类对象时

使用
匿名内部类在方法中定义时可以直接使用类型外部的局部变量(JDK1.8之前需要使用final修饰),但方法的局部变量对于匿名内部类而言是只读的。
匿名内部类在编译成class文件时,文件名为外部类名后拼接美元符号再拼接出现匿名内部类的顺序。
父类或接口 引用名=new 父类或接口名(){
//匿名内部类成员
}

示例

随机生成两个汉字
public class DemoAnonymoseClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Runnable task = new Runnable() {
			private Random rand  = new Random();
			
			private String buildName() {
				StringBuilder nameBuilder = new StringBuilder();
				// 4E00 - 9FA5
				nameBuilder.append((char)(rand.nextInt(0x9fa5-0x4e00)+0x4e00));
				nameBuilder.append((char)(rand.nextInt(0x9fa5-0x4e00)+0x4e00));
				return nameBuilder.toString();
			}
			
			private String name;
			@Override
			public void run() {
				while(true) {
					name = buildName();
					System.out.println(name);
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		};
		
		new Thread(task).start();
		// 重写父类Object的toString方法
		Object obj = new Object() {
			@Override
			public String toString() {
				return "自定义方法的对象输出";
			}
		};
		System.out.println(obj);
	}

}

三、Lambda表达式

3.1、说明
Lambda表达式目标使用最小可能的语法定义函数
Lambda表达式本质上上就是Java中的函数式编程
Lambda表达式产生的是函数而不是类型,在Java的虚拟机中所有东西都是类型,因此虚拟机在后台做了很多操作让Lambda表达式看起来更像函数
Lambda表达式在语法上更可能的灵活,以便于开发和使用
如果可以推到出lambda表达式的参数类型,则可以忽略其类型。
如果方法只有一个参数,而且这个参数可以推到得出,可以省略这个括号
lambda表达式的返回类型总是会由上下文推到得出
功能接口是仅包含一个抽象方法的任何接口 。(一个功能接口可能包含一个或多个 默认方法或 静态方法。)由于一个功能接口仅包含一个抽象方法,因此在实现该方法时可以省略该方法的名称。为此,您可以使用lambda表达式(而不是使用匿名类表达式)

3.2、语法
参数、箭头(->)、表达式

(String first,String second)->
first.length()-cecond.langth()
//检查一个字符串比另一个字符串短

方法
把代码放在{}中,并包含显示的return

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

如果没有参数,仍要提供括号

()->{for(i=0;i<100;i++)System.out.println(i);}

四、方法引用

说明
当Lambda表达式只是需要调用一个已经存在的方法即可实现时,此时使用方法的引用替代Lambda表达式。
方法主要关注方法,要求接口的实现方法与被引用的方法在返回值类型、参数列表上完全相同
被引用的可以是对象上的方法,也可以是类型上的方法
可以人为方法引用是Lambda表达式的一种升级版本。
静态方法引用

接口 引用名称= 类型或接口名称::方法名;

对象方法引用

接口 引用名称= 对象::方法名;

本地类:如果您需要创建一个类的多个实例,访问其构造函数或引入新的命名类型(例如,因为稍后需要调用其他方法),请使用它。

匿名类:如果需要声明字段或其他方法,请使用它。

Lambda表达式:

如果要封装要传递给其他代码的单个行为单位,请使用它。例如,如果要在集合的每个元素上执行特定操作,流程完成或流程遇到错误时,可以使用lambda表达式。

如果您需要功能接口的简单实例并且不符合上述条件(例如,不需要构造函数,命名类型,字段或其他方法),请使用它。

嵌套类:如果您的要求与本地类的要求相似,并且您想使该类型更广泛地使用,并且您不需要访问本地变量或方法参数,请使用它。

如果您需要访问封闭实例的非公共字段和方法,请使用非静态嵌套类(或内部类)。如果您不需要此访问,请使用静态嵌套类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值