在java程序中调用方法时,必须严格按照方法定义的变量进行参数传递。可是在开发过程当中可能会出现一种状况:不肯定要传递的参数个数。解决这个问题的思路是将多个参数封装为数组。这是一个打折扣的方法,由于数组并不表明任意多个数据。java
在JDK1.5中,引入了可变参数的概念。可变参数的语法形式为:express
[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; } }
java中的foreach语句是一种增强型for循环操做。for循环的输出方式须要控制索引,过于麻烦。所以,在JDK1.5中引入foreach形式。app
for(数据类型 变量:数组/集合){ //每一次循环,会将数组内容赋值个变量 }
每次循环自动将数组或集合的内容取出,避免了索引问题。ide
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(); } } }
静态导入能够减小代码量,可是过多的静态导入会下降代码的可读性。this
JDk5提供泛型技术。类属性或方法的参数在定义数据类型时,能够直接使用一个标记进行占位,再具体使用时才设置其对应的实际数据类型。这样当设置的数据类型出现错误后,就能够在程序编译时检测出来。使用泛型时,可以采用的类型只能是类,也就是说不能是基本类型,只能是引用类型。例如泛型采用整型,应用Integer,而不是int。设计
class Point<T>{ 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<Integer> 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<T>,Message<String>和Message<Integer>虽然都是Message类的对象,但这两个对象不可以直接进行引用传递操做。经过使用通配符“?”解决参数传递问题。通配符能够接受类对象,可是不能修改对象属性。code
class Message<T>{ 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<Integer> m1 = new Message<>(); Message<String> 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 类
设置泛型下限,在方法中使用。表示只能设置该类或其父类。
泛型能够定义在接口上。使用接口必须定义相应子类。对于使用泛型的接口,有两种实现方式。一是在子类继续设置泛型标记。二是在子类中为父类接口明肯定义一个泛型类型。
泛型也能够在方法中定义。在方法中定义泛型时,方法不必定要在泛型类中定义,但要在方法返回值类型前明肯定义泛型类型。
JDK1.5提出并应用了注解技术。在java SE中,最多见的Annotation是:
@Override
准确覆写操做。保证子类覆写的方法是父类中定义过的方法。当覆写方法出现错误时,能够在编译时检查出来。
@Deprecated
声明过时操做。用于声明过时不建议使用的方法。
@SuppressWarnings
压制警告。开发者明确知道会出现警告信息却执意按照固定方式处理,可使用@SuppressWarnings压制出现的警告信息。
class Book<T>{ 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定义的普通方法,须要利用实例化对象明确调用。在接口中定义静态方法,该方法能够由接口名称直接调用。
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<P,R>{ public R change(P p); } public class method_reference_static{ public static void main(String args[]){ //将String.valueOf()方法变为IMessage接口的change()方法 //valueOf()方法接收int型数据,返回String型数据 Imessage<Integer, String> msg = String::valueOf; String str = msg.change(1000); System.out.println(str.replaceAll("0","9")); } }
实例化对象::普通方法
@FunctionalInterface interface IMessage<R>{ public R upper(); } public class method_reference_common{ public static void main(String args[]){ //String类的toUpperCase()定义:public String toUpperCase()。 //该方法没有参数,有返回值。 IMessage<String> msg = "hello"::toUpperCase; String str = msg.upper(); System.out.println(str); } }
特定类::普通方法
@FunctionalInterface interface IMessage<P>{ public int compare(P p1, P p2); } public class method_reference_special{ public static void main(String args[]){ IMessage<String> msg = String::compareTo; System.out.println(msg.compare("A","B")); } }
类名称::new
@FunctionalInterface interface IMessage<C>{ 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<Book> msg = Book::new; //引用构造方法 Book book = msg.create("JAVA", 100); System.out.println(book); } }
方法引用操做可能出现的函数式接口有四类:有参数有返回值、有参数无返回值、无参数有返回值、判断真假。JDK1.8提供了一个新的开发包:
java.util.function
该开发包提供四个核心函数式接口,简化开发者的定义,实现操做的统一。
一、功能型接口
@FunctionalInterface public interface Function<T,R>{ public R apply(T t); //接收**一个**参数,并返回一个处理结果 }
import java.util.function.Function; public class funcifc_function{ public static void main(String args[]){ Function<String, Boolean> fun = "##hello"::startsWith; //利用对象调用startsWith() System.out.println(fun.apply("##")); } }
注意引用的方法只能有一个输入和一个返回结果。不然,引用方法不能与apply()匹配。
二、消费型接口
@FunctionalInterface public interface Comsumer<T>{ public void accept(T t); //只接收数据,不返回结果 }
import java.util.function.Consumer; public class funcifc_consumer{ public static void main(String[] args){ Consumer<String> cons = System.out::print; cons.accept("hello world"); } }
三、供给型接口
@FunctionalInterface public interface Supplier<T>{ public T get(); //不接收数据,只返回结果 }
import java.util.function.Supplier; public class funcifc_supplier{ public static void main(String args[]){ Supplier<String> sup = "hello"::toUpperCase; System.out.println(sup.get()); } }
四、断言型接口
@FunctionalInterface public intereface Predicate<T>{ public boolean test(T t); //判断 }
import java.util.function.Predicate; public class funcifc_predicate{ public static void main(String args[]){ Predicate<String> pre = "hello"::equalsIgnoreCase; System.out.println(pre.test("HELLO")); } }