java5新特性 可变参数_java5-8新特性的理解

可变参数

在java程序中调用方法时,必须严格按照方法定义的变量进行参数传递。但是在开发过程中可能会出现一种情况:不确定要传递的参数个数。解决这个问题的思路是将多个参数封装为数组。这是一个打折扣的方法,因为数组并不代表任意多个数据。

在JDK1.5中,引入了可变参数的概念。可变参数的语法形式为:

[public/protected/private] [static/final/abstract] 返回值类型 func(参数类型 ... 变量){

[return [返回值] ;]

}

参数变量传递到方法中,以指定类型的数组进行保存。

public class varargs{

public static void main(String args[]){

System.out.println(add(1,2,3));

System.out.println(add(10,20));

}

public static int add(int ... data){

int sum = 0;

for(int i = 0; i < data.length; i++){

sum += data[i];

}

return sum;

}

}

foreach循环

java中的foreach语句是一种加强型for循环操作。for循环的输出方式需要控制索引,过于麻烦。因此,在JDK1.5中引入foreach形式。

for(数据类型 变量:数组/集合){

//每一次循环,会将数组内容赋值个变量

}

每次循环自动将数组或集合的内容取出,避免了索引问题。

public class foreach{

public static void main(String args[]){

int data[] = new int[]{1,2,3,4,5};

for(int x : data){

System.out.println(x + " ");

}

}

静态导入

如果一个类中的方法全部属于static型方法,其他类在引用此类时,必须先使用import导入所需要的包。然后使用“类名.方法()”进行调用。

如果在调用这些方法时不希望出现类的名称,JDK1.5引入静态导入功能。

import static 包.类.*;

package com.qi.demo;

public class myMath{

public static int div(int x, int y) throws Exception{

System.out.println("===start===");

int result = 0;

try{

result = x / y;

}catch(Exception e){

throw e;

}finally{

System.out.println("===end===");

}

return result;

}

public static int add(int x, int y){

return x + y;

}

}

import static com.qi.demo.myMath.*;

public class static_import{

public static void main(String args[]){

System.out.println("Add operation:" + add(10,20));

try{

System.out.println("divide operation: " + div(10,2));

}catch(Exception e){

e.printStackTrace();

}

}

}

静态导入可以减少代码量,但是过多的静态导入会降低代码的可读性。

泛型

JDk5提供泛型技术。类属性或方法的参数在定义数据类型时,可以直接使用一个标记进行占位,再具体使用时才设置其对应的实际数据类型。这样当设置的数据类型出现错误后,就可以在程序编译时检测出来。使用泛型时,能够采用的类型只能是类,也就是说不能是基本类型,只能是引用类型。例如泛型采用整型,应用Integer,而不是int。

class Point{

private T x;

private T y;

public void setX(T x){

this.x = x;

}

public void setY(T y){

this.y = y;

}

public T getX(){

return x;

}

public T getY(){

return y;

}

}

public class generic{

public static void main(String args[]){

Point p = new Point<>();

p.setX(10);

p.setY(20);

Integer x = p.getX();

Integer y = p.getY();

System.out.println("coordinate x: " + x + " y: " +y);

}

}

通配符

对于同一类,由于设置泛型类型不同,其对象表示的含义也不同,因此不能够直接进行引用操作。例如通过泛型定义Message,Message和Message虽然都是Message类的对象,但这两个对象不能够直接进行引用传递操作。通过使用通配符“?”解决参数传递问题。通配符可以接受类对象,但是不能修改对象属性。

class Message{

private T msg;

public void setMsg(T msg){

this.msg = msg;

}

public T getMsg(){

return msg;

}

}

public class generic_wildcard{

public static void main(String args[]){

Message m1 = new Message<>();

Message m2 = new Message<>();

m1.setMsg(100);

m2.setMsg("hello");

fun(m1);

fun(m2);

}

public static void fun(Message> temp){

System.out.println(temp.getMsg());

}

}

在“?”通配符的基础上还有两个子通配符。

? extends 类

设置泛型上限,在声明和方法中使用。表示可以设置该类或其子类。

? super 类

设置泛型下限,在方法中使用。表示只能设置该类或其父类。

泛型接口

泛型可以定义在接口上。使用接口必须定义相应子类。对于使用泛型的接口,有两种实现方式。一是在子类继续设置泛型标记。二是在子类中为父类接口明确定义一个泛型类型。

泛型方法

泛型也可以在方法中定义。在方法中定义泛型时,方法不一定要在泛型类中定义,但要在方法返回值类型前明确定义泛型类型。

Annotation

JDK1.5提出并应用了注解技术。在java SE中,最常见的Annotation是:

@Override

准确覆写操作。保证子类覆写的方法是父类中定义过的方法。当覆写方法出现错误时,可以在编译时检查出来。

@Deprecated

声明过期操作。用于声明过期不建议使用的方法。

@SuppressWarnings

压制警告。开发者明确知道会出现警告信息却执意按照固定方式处理,可以使用@SuppressWarnings压制出现的警告信息。

class Book{

private T title;

public void setTitle(T title){

this.title = title;

}

public T getTitle(){

return title;

}

}

public class annotation_suppresswarnings{

@SuppressWarnings({"rawtypes", "unchecked"})

public static void main(String args[]){

Book book = new Book();

book.setTitle("hello");

System.out.println(book.getTitle());

}

}

接口定义加强

JDK1.8开始,接口中可以定义普通方法与静态方法。java增加这个特性原因如下。随着接口的子类越来越多,如果这个接口功能不足,需要增加新的方法,则需要对所有接口子类覆写新增加的方法。这个设计的工作量是重复的且是巨大的,因此通过放宽接口定义,接口可以定义普通方法和静态方法,接口的方法扩充问题就能得到很好的解决。

在接口中定义普通方法,该方法必须使用default来进行定义。使用default定义的普通方法,需要利用实例化对象明确调用。在接口中定义静态方法,该方法可以由接口名称直接调用。

lambda表达式

JDK1.8中引入lambda表达式。lambda表达式是应用在单一抽象方法接口环境下的一种简化定义形式,解决匿名内部类定义复杂问题。单一抽象方法接口使用@FunctionalInterface注解,表示此为函数式接口,里面只允许定义一个抽象方法。lambda表达式有三种形式。

(params) -> expression

(params) -> statement

(params) -> {statements}

@FunctionalInterface

interface IMessage{

public int add(int ... args);

static int sum(int ... args){

int sum = 0;

for(int temp:args){

sum += temp;

}

return sum;

}

}

public class lambda{

public static void main(String args[]){

//()内是参数,->后是子类覆写抽象方法的方法体

fun((int ... param) -> IMessage.sum(param));

}

public static void fun(IMessage msg){

System.out.println(msg.add(10,20,30));

}

}

方法引用

JDK1.8支持方法的引用操作,相当于为方法定义别名。java8定义了四种方法引用操作形式。

引用静态方法

类名称::static方法名称

interface Imessage

{

public R change(P p);

}

public class method_reference_static{

public static void main(String args[]){

//将String.valueOf()方法变为IMessage接口的change()方法

//valueOf()方法接收int型数据,返回String型数据

Imessage msg = String::valueOf;

String str = msg.change(1000);

System.out.println(str.replaceAll("0","9"));

}

}

引用某个对象的方法

实例化对象::普通方法

@FunctionalInterface

interface IMessage{

public R upper();

}

public class method_reference_common{

public static void main(String args[]){

//String类的toUpperCase()定义:public String toUpperCase()。

//该方法没有参数,有返回值。

IMessage msg = "hello"::toUpperCase;

String str = msg.upper();

System.out.println(str);

}

}

引用特定类型的方法

特定类::普通方法

@FunctionalInterface

interface IMessage

{

public int compare(P p1, P p2);

}

public class method_reference_special{

public static void main(String args[]){

IMessage msg = String::compareTo;

System.out.println(msg.compare("A","B"));

}

}

引用构造方法

类名称::new

@FunctionalInterface

interface IMessage{

public C create(String t, double p);

}

class Book{

private String title;

private double price;

public Book(String title, double price){

this.title = title;

this.price = price;

}

@Override

public String toString(){

return "book: " + this.title + ", price: " + this.price;

}

}

public class metheod_reference_constructor{

public static void main(String args[]){

IMessage msg = Book::new; //引用构造方法

Book book = msg.create("JAVA", 100);

System.out.println(book);

}

}

内建函数式接口

方法引用操作可能出现的函数式接口有四类:有参数有返回值、有参数无返回值、无参数有返回值、判断真假。JDK1.8提供了一个新的开发包:

java.util.function

该开发包提供四个核心函数式接口,简化开发者的定义,实现操作的统一。

1、功能型接口

@FunctionalInterface

public interface Function{

public R apply(T t); //接收**一个**参数,并返回一个处理结果

}

import java.util.function.Function;

public class funcifc_function{

public static void main(String args[]){

Function fun = "##hello"::startsWith; //利用对象调用startsWith()

System.out.println(fun.apply("##"));

}

}

注意引用的方法只能有一个输入和一个返回结果。否则,引用方法不能与apply()匹配。

2、消费型接口

@FunctionalInterface

public interface Comsumer{

public void accept(T t); //只接收数据,不返回结果

}

import java.util.function.Consumer;

public class funcifc_consumer{

public static void main(String[] args){

Consumer cons = System.out::print;

cons.accept("hello world");

}

}

3、供给型接口

@FunctionalInterface

public interface Supplier{

public T get(); //不接收数据,只返回结果

}

import java.util.function.Supplier;

public class funcifc_supplier{

public static void main(String args[]){

Supplier sup = "hello"::toUpperCase;

System.out.println(sup.get());

}

}

4、断言型接口

@FunctionalInterface

public intereface Predicate{

public boolean test(T t); //判断

}

import java.util.function.Predicate;

public class funcifc_predicate{

public static void main(String args[]){

Predicate pre = "hello"::equalsIgnoreCase;

System.out.println(pre.test("HELLO"));

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值