Java--枚举

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     }
原文地址:https://www.cnblogs.com/woainifanfan/p/6774639.html