1.自定义枚举类:有限个对象,单例模式,多个确定的对象是枚举类,Java的关键字enurm;
例如月份类,周期类 是枚举类有限个对象---枚举类具体表现---单例形式:单例指的一个类只有一个实例对象
对于枚举 有多个确定的对象,类似于单例的构造方式:
下面是 使用枚举类的实现,---类似于单例模式的构造方法UI杨
1.私有化的构造器,2.指向自己内部类的实例的静态引用 3.返回实例的静态的公有方法--返回自己实例
1 class Season 2 { 3 //1.提供类的属性声明 private final 4 private final String seasonName; 5 private final String seasonDesc; 6 private Season (String seasonname, String seasondesc) 7 { 8 this.seasonDesc=seasondesc; 9 this.seasonName=seasonname; 10 } 11 12 //2.通过公共方式进行调用 13 public String getSeasonName() { 14 return seasonName; 15 } 16 17 // 创建一个枚举类的内部类对象,SingleTon下对象 静态的实例 18 public static final Season SPRING=new Season("Spring","1-4"); 19 public static final Season SUMMER=new Season("SUMMER","5-7"); 20 public static final Season AUTUMN=new Season("AUTUMN","8-10"); 21 public static final Season WINTER=new Season("WINTER","11-12"); 22 23 @Override 24 public String toString() { 25 return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]"; 26 } 27 28 public String getSeasonDesc() { 29 return seasonDesc; 30 } 31 32 33 34 }
2.使用 JDK 1.5 使用enum关键字定义枚举类:第一步必须先实例化对象,对象用,分开
|-----如何让枚举类实现接口,每一个实例对象重写抽象方法,枚举类中每个实例调用重写的抽象方法
1 // 得到所有枚举类的对象返回的是数组 2 Seanson[] seansons=Seanson.values(); 3 4 // 2.字符串 必须枚举类对象名 5 Seanson sea=Seanson.valueOf("SPRING");
1 enum Seanson { 2 3 // 1.首先先实例化对象,对象之间用,隔开 4 SPRING("Spring","1-4"), 5 SUMMER("SUMMER","5-7"), 6 AUTUMN("AUTUMN","8-10"), 7 WINTER("WINTER","11-12"); 8 9 10 //1.提供类的属性声明 private final 11 private final String seasonName; 12 private final String seasonDesc; 13 private Seanson (String seasonname, String seasondesc) 14 { 15 this.seasonDesc=seasondesc; 16 this.seasonName=seasonname; 17 } 18 @Override 19 public String toString() { 20 return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]"; 21 } 22 23 public String getSeasonDesc() { 24 return seasonDesc; 25 } 26 27 }
3.枚举类实现 接口,每一个实例化对象重写 抽象方法
1 package testException; 2 3 enum Seanson implements Info{ 4 5 // 1.首先先实例化对象,对象之间用,隔开---每一个对象重写 抽象方法 6 SPRING("Spring","1-4"){ 7 public void show() 8 { 9 System.out.println("春天在哪里"); 10 } 11 }, 12 SUMMER("SUMMER","5-7") 13 { 14 public void show() 15 { 16 System.out.println("夏天在哪里"); 17 } 18 }, 19 AUTUMN("AUTUMN","8-10"), 20 WINTER("WINTER","11-12"); 21 22 23 //1.提供类的属性声明 private final 24 private final String seasonName; 25 private final String seasonDesc; 26 private Seanson (String seasonname, String seasondesc) 27 { 28 this.seasonDesc=seasondesc; 29 this.seasonName=seasonname; 30 } 31 @Override 32 public String toString() { 33 return "Season [seasonName=" + seasonName + ", seasonDesc=" + seasonDesc + "]"; 34 } 35 36 public String getSeasonDesc() { 37 return seasonDesc; 38 } 39 40 @Override 41 public void show() { 42 // TODO Auto-generated method stub 43 44 } 45 46 47 48 } 49 50 interface Info{ 51 public void show(); 52 }
java增加对元数据(MetaData)的支持,也就是Annotation
|----如何自定义注解
|---元注解--对注解知识的解释
使用@添加符号:将Annotation当成一个修饰符使用:三个基本的注解:@Override @Deprecated @SuppressWarnings
显示表明 此方法是重写--有利于对编译错误检测
java中声明注解 @interface Myannotation
java 元Annotation修饰其他Annotation---相当于元注解
元数据修饰实在数据较元数据
@Retention:指定该Annotation的生命周期:主要三种形式:SOURCE,CLASS,RUNTIME
@Target:修饰那些程序
@Inherited:Annotation具有继承性
对单例模式的定义:确保一个类只有一个实例,自行实例化并向整个系统提供这个实例,
在Servlet容器,对于同一个Servlet类多个业务请求,只实例化一个servlet对象,多个业务请求使用同一个servlet单例对象,
对于单例模式的特点:
1.拥有一个私有的构造器---防止类在外部实例化(java反射机制中实例化构造方法是private的类,破坏单例的性质)
2.类的内部实例化态对象的静态引用(实例是静态的对象)
3.公共返回此实例的静态的方法
问题:
1.使用单例模式的时候 不要用反射,自动创建新的对象
2.多个线程竞争一个线程,注意线程安全问题
3. 单例化根据实例化对象 分为三种:懒汉式单例、饿汉式单例、登记式单例三种,主要运用在打印机服务,线程池和缓存 避免不一致的模式
饿汉式单例:不管之前是否存在马上创建一个单例,
1 public class Singleton { 2 private static Singleton singleton = new Singleton(); 3 private Singleton(){} 4 public static Singleton getInstance(){ 5 return singleton; 6 } 7 }
懒汉式单例:只在没有的话才会创建--注意线程安全性
如果并没有加上sychronized关键字 当两个线程A与线程B进行访问到 if 时候会创建两个单例对象,对方法进行上锁操作
public class Singleton { private static Singleton singleton; private Singleton(){} public static synchronized Singleton getInstance(){ if(singleton==null){ singleton = new Singleton(); } return singleton; } }
事实上对方法进行同步的话,每一时刻只有一个线程进行到方法,修改不进行同步方法,进行同步模块的处理 采用双重验证方式,
原因;线程A和线程B运行到 synchronized(singleton.getClass()) ,即使线程B得到锁创建一个对象,但是在此时线程A并没有判断singleton==null,线程A还会创建新的对象
导致 线程A与线程B采用两个不同的单例模式,所以采用双重验证方式
事实上双重检验由于JVM内存平台支持无序写入,并不能双重检验时刻成功,因此 在平台上运行,采用同步方法(在方法上加上sychronized)最好的:虽然效率低但是线程绝对安全
1 private static SingleTon singleton=null; 2 private SingleTon(){}; 3 4 public static SingleTon getInstance() 5 {//采用双重验证方式,多个线程共享一个单例实例 6 if(singleton==null) 7 { 8 synchronized(SingTon.Class) 9 { 10 if(singleton==null) 11 singleton=new SingleTon(); 12 } 13 } 14 return singleton; 15 }