一、枚举

通过enum关键字来实现枚举,在枚举中需要注意的有:

1. 枚举中的属性必须放在最前面,一般使用大写字母表示

2. 枚举中可以和java类一样定义方法

3. 枚举中的构造方法必须是私有的

通过一个java类来模拟枚举的功能:

package org.lkl.imitate_enum;

public abstract class WeekDay {
public static final WeekDay SUN = new WeekDay() { @Override
public WeekDay nextDay() {
return MON;
}
};
public static final WeekDay MON = new WeekDay() { @Override
public WeekDay nextDay() {
return SUN;
} }; @Override
public String toString() {
return this == SUN ?"SUN星期天":"MON星期一" ;
} public abstract WeekDay nextDay(); public static void main(String[] args) {
System.out.println(WeekDay.SUN.nextDay());
System.out.println(WeekDay.MON.nextDay());
}
}

4.可以在枚举属性后面添加()来调用指定参数的构造方法,添加{}来实现其对应的匿名内部类,例如:

package org.lkl.imitate_enum;
public enum TrafficLamp {
RED(30){
public TrafficLamp nextLamp() {
return GREEN ;
}
},
GREEN(20){
public TrafficLamp nextLamp() {
return YELLOW ;
}
},
YELLOW(10){
public TrafficLamp nextLamp() {
return RED ;
}
} ;
public abstract TrafficLamp nextLamp() ;
private int time ;
private TrafficLamp(int time){
this.time = time ;
System.out.println(time);
} public static void main(String[] args) {
System.out.println(TrafficLamp.GREEN);
}
}

二、通过枚举来实现单例

实现单例的核心在于private私有化类中的构造方法,在枚举中的构造方法必须是私有的,这就为枚举来实现单例奠定了基础。下面以数据源中获得Connection连接来举例:

在开发中经常是通过数据源来获得数据库的Connection,数据源的实现方式有多种,最典型的有两种,一种是C3P0,另外一种是DBCP(以后有机会再针对两种数据源进行讨论),这里以C3P0数据源为例。由于数据源的创建与销毁都是十分消耗性能的,并且系统中有一个数据源一般就能满足开发的要求,因此要将数据源设计为单例。

采用分散配置,创建一个jdbc.propertis文件,其内容如下:

driverClass = com.mysql.jdbc.Driver
jdbcUrl = jdbc:mysql://localhost:3306/liaokailin
user = root
password = mysqladmin
maxPoolSize = 20
minPoolSize = 5

创建一个MyDataBaseSource的枚举:

package org.lkl.imitate_enum;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ResourceBundle; import com.mchange.v2.c3p0.ComboPooledDataSource; public enum MyDataBaseSource {
DATASOURCE;
private ComboPooledDataSource cpds = null; private MyDataBaseSource() {
try { /*--------获取properties文件内容------------*/
// 方法一:
/*
* InputStream is =
* MyDBSource.class.getClassLoader().getResourceAsStream("jdbc.properties");
* Properties p = new Properties(); p.load(is);
* System.out.println(p.getProperty("driverClass") );
*/ // 方法二:(不需要properties的后缀)
/*
* ResourceBundle rb = PropertyResourceBundle.getBundle("jdbc") ;
* System.out.println(rb.getString("driverClass"));
*/ // 方法三:(不需要properties的后缀)
ResourceBundle rs = ResourceBundle.getBundle("jdbc");
cpds = new ComboPooledDataSource();
cpds = new ComboPooledDataSource();
cpds.setDriverClass(rs.getString("driverClass"));
cpds.setJdbcUrl(rs.getString("jdbcUrl"));
cpds.setUser(rs.getString("user"));
cpds.setPassword(rs.getString("password"));
cpds.setMaxPoolSize(Integer.parseInt(rs.getString("maxPoolSize")));
cpds.setMinPoolSize(Integer.parseInt(rs.getString("minPoolSize")));
System.out.println("-----调用了构造方法------");
;
} catch (Exception e) {
e.printStackTrace();
}
} public Connection getConnection() {
try {
return cpds.getConnection();
} catch (SQLException e) {
return null;
}
} }

测试代码:

package org.lkl.imitate_enum;

public class Test {
public static void main(String[] args) {
MyDataBaseSource.DATASOURCE.getConnection() ;
MyDataBaseSource.DATASOURCE.getConnection() ;
MyDataBaseSource.DATASOURCE.getConnection() ;
}
}

结果如下:

-----调用了构造方法------
2013-7-17 17:10:57 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge16d8v1tgb0wppydrzz|2c1e6b, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge16d8v1tgb0wppydrzz|2c1e6b, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/kaoqin, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]

很显然获得了三个Connection连接,但是只调用了一次枚举的构造方法,从而通过枚举实现了单例的设计

通过枚举enum实现单例设计的更多相关文章

  1. 通过枚举enum实现单例

    通过enum关键字来实现枚举,在枚举中需要注意的有: 1. 枚举中的属性必须放在最前面,一般使用大写字母表示 2. 枚举中可以和java类一样定义方法 3. 枚举中的构造方法必须是私有的 enum S ...

  2. 简单介绍如何使用PowerMock和Mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值(转)

    本文将简单介绍如何使用PowerMock和Mockito来mock1. 构造函数2. 静态函数3. 枚举实现的单例4. 选择参数值做为函数的返回值5. 在调用mock出来的方法中,改变方法参数的值 一 ...

  3. php : 单例设计演示

    单例 : 保证只有一个实例 <?php /* * 单例设计 */ // 单例: 只能"创造"出它的一个对象实例 class Single{ // 第一步: 私有化构造方法 p ...

  4. Spring容器-ApplicationContext的单例设计

    Spring容器-ApplicationContext的单例设计   每次通过new创建一个ApplicationContext容器,都会执行refresh方法,看源代码了解到这个refresh方法会 ...

  5. Swift中简单的单例设计

    import Foundation class Test: NSObject { // 提供单例实例 static let shareInstance = Test() // 私有化构造方法 over ...

  6. JAVA设计模式:单例设计

    1.单例设计Singleton的引出 单例设计,从名字上首先可以看出单---即只有一个,例---只的是实例化对象:那么单例也就是说一个类,只产生了一个实例化对象.但是我们都知道,一个类要产生实例化对象 ...

  7. 算法、数据结构、与设计模式等在游戏开发中的运用 (一):单例设计(Singleton Design)

    算法.数据结构.与设计模式等在游戏开发中的运用 (一):单例设计(Singleton Design) 作者: Compasslg 李涵威 1. 什么是单例设计(Singleton Design) 在学 ...

  8. Effective Java —— 用私有构造器或枚举类型强化单例属性

    本文参考 本篇文章参考自<Effective Java>第三版第三条"Enforce the singleton property with a private construc ...

  9. (一二三)基于GCD的dispatch_once实现单例设计

    要实现单例,关键是要保证类的alloc和init只被调用一次,并且被自身强引用防止释放. 近日读唐巧先生的<iOS开发进阶>,受益匪浅,通过GCD实现单例就是收获之一,下面把这个方法与大家 ...

随机推荐

  1. Qt一步一步实现插件调用(附源码)

    最近手里几个项目都采用插件的方式进行开发工作,这里记录一下实现方法,给需要的同学一个参考, 在linux系统和window系统都能成功编译通过,不废话直接步骤 第一步:建立插件原型 新建一个Qt项目, ...

  2. Spring boot将配置属性注入到bean类中

    一.@ConfigurationProperties注解的使用 看配置文件,我的是yaml格式的配置: // file application.yml my: servers: - dev.bar.c ...

  3. poi导出word

    最近做了个poi导出word的功能 下面是代码: 一个可以参考的例子: package com.lzb.crm.web; import java.io.FileOutputStream; import ...

  4. 有两个数a,b,请写一个函数交换a,b

    题目:有两个数a,b,请写一个函数交换a,b,具体实现如下: #include<stdlib.h> #include<stdio.h> int swap(int * pA, i ...

  5. sql server 修改字段大小

    alter table AAA ALTER COLUMN BBBvarchar(100);  这种语法只适合把字段往大了设置,  如果更新的字段大小比实际的要小时,并且数据库已存在比要更新的数据大时, ...

  6. C#中两个时间的比较

    var DateTimedt1 = Convert.ToDateTime(dt);     var DateTimedt2 = Convert.ToDateTime(DateTime.Now);    ...

  7. Binary Tree Level Order Traversal II——LeetCode

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left ...

  8. HDOJ(HDU) 2088 Box of Bricks(平均值)

    Problem Description Little Bob likes playing with his box of bricks. He puts the bricks one upon ano ...

  9. iOS图片处理

    http://www.cnblogs.com/kenshincui/p/3959951.html

  10. 经典C面试题

    12个有趣的C语言面试题 面试题C 摘要:12个C语言面试题,涉及指针.进程.运算.结构体.函数.内存,看看你能做出几个! 1.gets()函数 问:请找出以下代码里的问题: #include< ...