一、可变参数
问题:一个方法接收的参数个数不固定
例如:
*System.out.println(add(2,3,5));
*System.out.println(add(1,2,3,5));
可变参数的特点:
1、只能出现在参数列表的最后;
2、...位于变量类型和变量名之间,前后有无空格都可以;
3、调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。
代码举例:
public static void main(String[] args) { System.out.println(add(2,3,4,5)); } public static int add(int x,int... args){//...位于数据类型和变量名之间 int sum = x; for(int i=0;i<args.length;i++){ sum += args[i];//方法体中以数组的形式来访问可变参数 } return sum; }
二、增强for循环
1、语法:
For(type 变量名 : 集合变量名){...}
2、注意事项:
*迭代变量必须在()中定义;
*集合变量可以是数组或实现了Iterable接口的集合类
注:Iterable接口:实现该接口允许对象成为“foreach”语句的目标。该接口从1.5开始的新特性。
实现该接口,覆写方法Iterator<T> iterator();返回一个在一组T类型的元素上进行迭代的迭代器。
3、代码举例:
public static void main(String[] args) { System.out.println(add(2,3,4,5)); } public static int add(int x,int... args){//...位于数据类型和变量名之间 int sum = x; for(int arg : args){ sum += arg; } return sum; }
三、基本数据类型的自动拆箱和装箱
自动装箱:
Integer iObj = 4;
自动拆箱:
System.out.println(iObj + 6);
对于基本数据类型的数据:当数据大小在-128~127之间时,自动装箱会装成同一个,当数据大于这个范围时,装箱时才会创建不同对象。
享元模式:当有很多小的对象有很多属性相同时,可以把它们变成一个对象,那些不同属性变成方法的参数,称之为外部状态,这些相同的属性称之为对象的内部状态。
四、枚举
好处:如果输入数据不符合规则时,不让你输入,将错误提前到了编译时期。
1、为什么要有枚举:
问题:要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一到星期天,但有人可能会写成int weekday = 0;
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
2、用普通类实现枚举功能,定义一个WeekDay的类来模拟枚举功能
*私有的构造方法
*每个元素分别用一个公有的静态成员变量表示
*可以有若干公有方法或抽象方法,例如,要提供nextDay方法必须是抽象的。采用抽象方法定义nextDay就将大量的if else语句转移成了一个个独立的类。
代码举例:
public abstract class WeekDay { private void WeekDay(){} public final static WeekDay SUN = new WeekDay(){ @Override public cn.itcast.day1.WeekDay nextDay() { return MON; }
}; public final static WeekDay MON = new WeekDay(){ @Override public cn.itcast.day1.WeekDay nextDay() { return TUE; }
}; public final static WeekDay TUE = new WeekDay(){
@Override public cn.itcast.day1.WeekDay nextDay() { return WED; }
}; public final static WeekDay WED = new WeekDay(){
@Override public cn.itcast.day1.WeekDay nextDay() {
return THU; }
}; public final static WeekDay THU = new WeekDay(){ @Override public cn.itcast.day1.WeekDay nextDay() { return FRI; }
}; public final static WeekDay FRI = new WeekDay(){ @Override public cn.itcast.day1.WeekDay nextDay() { return SAT; }
}; public final static WeekDay SAT = new WeekDay(){ @Override public cn.itcast.day1.WeekDay nextDay() { return SUN; }
}; public abstract WeekDay nextDay(); /* public WeekDay nextDay(){ if (this == SUN){ return MON; }else if(this == MON){ return TUE; }else if(this == TUE){ return WED; }else if(this == WED){ return THU; }else if(this == THU){ return FRI; }else if(this == FRI){ return SAT; }else{ return SUN; } } */ public String toString(){ if (this == SUN){ return "SUN"; }else if(this == MON){ return "MON"; }else if(this == TUE){ return "TUE"; }else if(this == WED){ return "WED"; }else if(this == THU){ return "THU"; }else if(this == FRI){ return "FRI"; }else{ return "SUN"; } } }
3、枚举的基本应用
*枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法;
*枚举元素必须位于枚举体中的最开始部分,枚举元素列表后要有分号与其他成员分隔。把枚举中的成员或变量等放在枚举元素的前面,编译器会报告错误。
*举例:定义一个WeekDay的枚举
public enum WeekDay{ SUN(1),MON,TUE,WED,THI,FRI,SAT; private WeekDay(){} private WeekDay(int day){}
}
*构造方法
在枚举类中,元素列表必须置于所有成员之前。
枚举的构造方法必须是私有的。
要调用带参数的构造方法,直接在元素后面加括号传入参数,枚举元素MON和MON()的效果一样,都是调用默认的构造方法。
匿名内部类想要调用父类有参数的构造方法,可以再new时括号内输入参数,如:new Date(300){};此时创建的匿名内部类对象为Date类子类对象,其调用的父类构造函数是带参数的构造函数。
*带方法的枚举:
**定义枚举TrafficLamp
**实现普通的next方法
**实现抽象方法next方法:每个元素分别是由枚举类的子类生成的实例对象,这些子类采用类似的内部类的方式进行定义。
**增加上表示时间的构造方法。
代码举例:
public enum TrafficLamp{ RED(30){ @Override public TrafficLamp nextLamp() { return GREEN; } }, GREEN(45){ @Override public TrafficLamp nextLamp() { return YELLOW; } }, YELLOW(5){
@Override public TrafficLamp nextLamp() { return RED ; } }; public abstract TrafficLamp nextLamp(); private int time; private TrafficLamp(int time){ this.time = time; } }
*枚举只有一个成员时,就可以作为一种单例的实现方式。
要创建单例可以使用枚举