本文共 7524 字,大约阅读时间需要 25 分钟。
1.1 自动装箱
-128~127 之间的整数,装在一个内存区域。
超过这个范围的整数,装在不同的内存区域。
1.2 自动拆箱
Integer i1=12;
System.out.println(i1 + 5);//17
1.3 享元模式 flyweight
如果很多很小的对象,他们有很多相同的东西,那就可以把它们变成一个东西;还有不一样的东西就变成外部属性,作为方法的参数传入。
package com.itcast.day1; public class AutoBox { public static void main(String[] args) { //-128~127之间 Integer i1=12; Integer i2=12; System.out.println(i1==i2);//true i1,i2被放置在同一内存区域 System.out.println(i1 + 5);//17 //大于127 Integer i3=134; Integer i4=134; System.out.println(i3 == i4);//false i3,i4被放置在不同的内存区域 //这不是自动装箱,而是手工调用valueOf这个静态方法, //把一个基本类型整数变成了一个包装类型对象。 Integer i5=Integer.valueOf(15); Integer i6=Integer.valueOf(15); System.out.println(i5 == i6);//true Integer i7=Integer.valueOf(156); Integer i8=Integer.valueOf(156); System.out.println(i7 == i8);//false /** * 在 包装类型内部,使用了享元模式,即: * * 如果很多很小的对象,他们有很多相同的东西, * 那就可以把它们变成一个东西; * 还有不一样的东西就变成外部属性,作为方法的参数传入。 */ } }
2.1 枚举是什么? 为什么要用枚举?
要定义星期几或者性别的变量,该怎么定义?
假设用1-7分别表示星期一到星期天,但有人有可能会写成 int weekDay=0;
枚举就是要让某个类型的变量的取值只能为若干个固定的值中的一个,否则,编译器就会报错。
枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
2.2 用普通类如何实现枚举功能,定义一个Weekday的类来模拟枚举功能。
私有的构造方法
每个元素分别用一个共有的静态成员表示 static final
可以有若干共有方法或抽象方法,例如,要提供nextDay方法必须是抽象的。
采用抽象方法定义nextDay就是将大量的if,else语句转换成一个一个独立的类。
//模拟枚举package com.itcast.day1; public abstract class WeekDay { //私有化构造 private WeekDay(){} //抽象方法,放在子类去实现 public abstract WeekDay nextDay(); public final static WeekDay SU=new WeekDay(){ @Override public WeekDay nextDay() { return MO; } @Override public String toString(){ return "SU"; } }; public final static WeekDay MO=new WeekDay(){ @Override public WeekDay nextDay() { return TU; } @Override public String toString(){ return "MO"; } }; public final static WeekDay TU=new WeekDay(){ @Override public WeekDay nextDay() { return WE; } @Override public String toString(){ return "TU"; } }; public final static WeekDay WE=new WeekDay(){ @Override public WeekDay nextDay() { return TH; } @Override public String toString(){ return "WE"; } }; public final static WeekDay TH=new WeekDay(){ @Override public WeekDay nextDay() { return FR; } @Override public String toString(){ return "TH"; } }; public final static WeekDay FR=new WeekDay(){ @Override public WeekDay nextDay() { return SA; } @Override public String toString(){ return "FR"; } }; public final static WeekDay SA=new WeekDay(){ @Override public WeekDay nextDay() { return SU; } @Override public String toString(){ return "SA"; } }; }
package com.itcast.day1;//测试public class EnumTest { public static void main(String[] args) { WeekDay weekDay=WeekDay.MO; System.out.println(weekDay); System.out.println(weekDay.nextDay()); } }
package com.itcast.day1;public enum WeekDay2 { SUN,MON,TUS,WEN,THI,FRI,STA; }package com.itcast.day1;public class SunEnumTest { public static void main(String[] args) { WeekDay2 weekDay=WeekDay2.MON; System.out.println(weekDay);//MON System.out.println(weekDay.name());//MON System.out.println(weekDay.ordinal());//1 System.out.println(weekDay.valueOf("MON"));//MON System.out.println(weekDay.values());// 枚举元素的数组 [Lcom.itcast.day1.WeekDay2;@133c5982 System.out.println(weekDay.values().length);//元素个数 7 } }
//枚举package com.itcast.day1;public enum WeekDay2 { SUN(2),MON(),TUS,WEN,THI,FRI,STA;//保证写在最前面 //构造需要私有,不被外人所知 private WeekDay2(){System.out.println("first");}//不带参数的构造方法 private WeekDay2(int day){System.out.println("second");}//带参数的构造方法 }
//测试package com.itcast.day1;public class SunEnumTest { public static void main(String[] args) { WeekDay2 weekDay=WeekDay2.MON; } }结果打印:second
first first first first first first
构造方法的枚举
- 构造方法必须定义为私有的。
- 如果有多个构造方法,该如何选择哪个构造方法?
- 枚举元素MON和MON()的效果一样,都是调用默认的构造方法。
带方法的枚举
- 定义枚举TrafficLamp
- 实现普通的next方法
- 实现抽象的next方法:每个元素分别是由枚举类的之类来生成的实例对象,这些子类采用类似内部类的方法进行定义。
- 增加上表示时间的构造方法
开始做,坚持做,重复做package com.itcast.day1;public class EnumTest { public static void main(String[] args)throws Exception { TrafficLamp tfl=TrafficLamp.RED; System.out.println(tfl); System.out.println(tfl.nextLamp()); for(String arg:args){ System.out.println(arg); } System.out.println("*************************"); /* 枚举自动生成一些方法,如 values()方法 * The compiler automatically adds some special methods when it creates an enum. * For example, they have a static values method that returns an array containing * all of the values of the enum in the order they are declared. */ for(TrafficLamp tf:TrafficLamp.values()){ System.out.println(tf); } /* 所有的枚举,都继承自java.lang.Enum * Note: All enums implicitly extend java.lang.Enum. Because a class can only extend one parent (see Declaring Classes), * the Java language does not support multiple inheritance of state and therefore an enum cannot extend anything else. */ Class clazz=TrafficLamp.class;//得到字节码 String supClassName=clazz.getSuperclass().getName(); System.out.println(supClassName);//java.lang.Enum clazz=Class.forName(supClassName); supClassName=clazz.getSuperclass().getName(); System.out.println(supClassName);//java.lang.Object } public enum TrafficLamp{ //RED,GREEN,YELLOW这些元素都是枚举TrafficLame的子类的实例 RED(30){ //内部类 @Override public TrafficLamp nextLamp() { //实现抽象方法 return GREEN; } }, GREEN(45){ @Override public TrafficLamp nextLamp() { return YELLOW; } }, YELLOW(5)/*调用YELLOW子类有参数构造,子类.super(5)调用了父类TrafficLamp的有参构造*/{ @Override public TrafficLamp nextLamp() { return RED; } }; private int time; public abstract TrafficLamp nextLamp();//抽象方法 private TrafficLamp(int time){ this.time=time;}//构造方法要私有化 @Override public String toString() { return this==RED?"RED : "+this.time:this==GREEN?"GREEN : "+this.time:"YELLOW : "+this.time; } }}/*** 运行结果:RED : 30GREEN : 45*************************RED : 30GREEN : 45YELLOW : 5java.lang.Enumjava.lang.Object */
转载地址:http://kxqbx.baihongyu.com/