- 浏览: 103539 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
u013246812:
谢谢博主帮我解决了问题,就是那个process.exitVal ...
Java执行Shell脚本超时控制 -
fireinjava:
fireinjava 写道配置好多哦 =.=
刚看了下,原来是 ...
Java Spring2.5 Remote Invoke HTTP Invoker -
fireinjava:
配置好多哦 =.=
Java Spring2.5 Remote Invoke HTTP Invoker -
lee79:
呵呵,讲的很对
Java执行Shell脚本超时控制 -
fangwei:
非常感谢!!!btw 你虽然用到了slf4j,却没有用到它的强 ...
Java执行Shell脚本超时控制
In prior releases, the standard way to represent an enumerated type was the int Enum pattern:
// int Enum Pattern - has severe problems!
public static final int SEASON_WINTER = 0;
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL = 3;
This pattern has many problems, such as:
-
Not typesafe
- Since a season is just an
int
you can pass in any other int value where a season is required, or add two seasons together (which makes no sense). -
No namespace
- You must prefix constants of an int enum with a string (in this case
SEASON_
) to avoid collisions with other int enum types. - Brittleness - Because int enums are compile-time constants, they are compiled into clients that use them. If a new constant is added between two existing constants or the order is changed, clients must be recompiled. If they are not, they will still run, but their behavior will be undefined.
- Printed values are uninformative - Because they are just ints, if you print one out all you get is a number, which tells you nothing about what it represents, or even what type it is.
It is possible to get around these problems by using the Typesafe Enum
pattern (see Effective
Java
Item 21),
but this pattern has its own problems: It is quite verbose, hence error
prone, and its enum constants cannot be used in switch
statements.
In 5.0, the Java™ programming language gets linguistic support for enumerated types. In their simplest form, these enums look just like their C, C++, and C# counterparts:
enum Season { WINTER, SPRING, SUMMER, FALL }
But appearances can be deceiving. Java programming language enums are far
more powerful than their counterparts in other languages, which are little
more than glorified integers. The new enum
declaration defines a
full-fledged class (dubbed an enum type
). In addition to solving all
the problems mentioned above, it allows you to add arbitrary methods and
fields to an enum type, to implement arbitrary interfaces, and more. Enum
types provide high-quality implementations of all the Object
methods.
They are Comparable
and Serializable
, and the serial form is
designed to withstand arbitrary changes in the enum type.
Here is an example of a playing card class built atop a
couple of simple enum types. The Card
class is immutable, and only
one instance of each Card
is created, so it need not override
equals
or hashCode
:
import java.util.*; public class Card { public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE } public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES } private final Rank rank; private final Suit suit; private Card(Rank rank, Suit suit) { this.rank = rank; this.suit = suit; } public Rank rank() { return rank; } public Suit suit() { return suit; } public String toString() { return rank + " of " + suit; } private static final List<Card> protoDeck = new ArrayList<Card>(); // Initialize prototype deck static { for (Suit suit : Suit.values()) for (Rank rank : Rank.values()) protoDeck.add(new Card(rank, suit)); } public static ArrayList<Card> newDeck() { return new ArrayList<Card>(protoDeck); // Return copy of prototype deck } }
The toString
method for Card
takes advantage of the toString
methods for
Rank
and Suit
. Note that the Card
class is
short (about 25 lines of code). If the typesafe enums (Rank
and
Suit
) had been built by hand, each of them would have been
significantly longer than the entire Card
class.
The (private) constructor of Card
takes two parameters, a
Rank
and a Suit
. If you accidentally invoke the constructor
with the parameters reversed, the compiler will politely inform you of your
error. Contrast this to the int
enum pattern, in which the
program would fail at run time.
Note that each enum type has a static values
method that returns
an array containing all of the values of the enum type in the order they
are declared. This method is commonly used in combination with the
for-each loop
to iterate over the values of an
enumerated type.
The following example is a simple program called Deal
that
exercises Card
. It reads two numbers from the command line,
representing the number of hands to deal and the number of cards per hand.
Then it creates a new deck of cards, shuffles it, and deals and prints the
requested hands.
import java.util.*; public class Deal { public static void main(String args[]) { int numHands = Integer.parseInt(args[0]); int cardsPerHand = Integer.parseInt(args[1]); List<Card> deck = Card.newDeck(); Collections.shuffle(deck); for (int i=0; i < numHands; i++) System.out.println(deal(deck, cardsPerHand)); } public static ArrayList<Card> deal(List<Card> deck, int n) { int deckSize = deck.size(); List<Card> handView = deck.subList(deckSize-n, deckSize); ArrayList<Card> hand = new ArrayList<Card>(handView); handView.clear(); return hand; } } $ java Deal 4 5 [FOUR of HEARTS, NINE of DIAMONDS, QUEEN of SPADES, ACE of SPADES, NINE of SPADES] [DEUCE of HEARTS, EIGHT of SPADES, JACK of DIAMONDS, TEN of CLUBS, SEVEN of SPADES] [FIVE of HEARTS, FOUR of DIAMONDS, SIX of DIAMONDS, NINE of CLUBS, JACK of CLUBS] [SEVEN of HEARTS, SIX of CLUBS, DEUCE of DIAMONDS, THREE of SPADES, EIGHT of CLUBS]
Suppose you want to add data and behavior to an enum. For example consider the planets of the solar system. Each planet knows its mass and radius, and can calculate its surface gravity and the weight of an object on the planet. Here is how it looks:
public enum Planet { MERCURY (3.303e+23, 2.4397e6), VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24, 6.37814e6), MARS (6.421e+23, 3.3972e6), JUPITER (1.9e+27, 7.1492e7), SATURN (5.688e+26, 6.0268e7), URANUS (8.686e+25, 2.5559e7), NEPTUNE (1.024e+26, 2.4746e7), PLUTO (1.27e+22, 1.137e6); private final double mass; // in kilograms private final double radius; // in meters Planet(double mass, double radius) { this.mass = mass; this.radius = radius; } public double mass() { return mass; } public double radius() { return radius; } // universal gravitational constant (m3 kg-1 s-2 ) public static final double G = 6.67300E-11; public double surfaceGravity() { return G * mass / (radius * radius); } public double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); } }
The enum type Planet
contains a constructor, and each enum
constant is declared with parameters to be passed to the constructor
when it is created.
Here is a sample program that takes your weight on earth (in any unit) and calculates and prints your weight on all of the planets (in the same unit):
public static void main(String[] args) { double earthWeight = Double.parseDouble(args[0]); double mass = earthWeight/EARTH.surfaceGravity(); for (Planet p : Planet.values()) System.out.printf("Your weight on %s is %f%n", p, p.surfaceWeight(mass)); } $ java Planet 175 Your weight on MERCURY is 66.107583 Your weight on VENUS is 158.374842 Your weight on EARTH is 175.000000 Your weight on MARS is 66.279007 Your weight on JUPITER is 442.847567 Your weight on SATURN is 186.552719 Your weight on URANUS is 158.397260 Your weight on NEPTUNE is 199.207413 Your weight on PLUTO is 11.703031
The idea of adding behavior to enum constants can be taken one step
further. You can give each enum constant a different
behavior
for some method. One way to do this by switching on the enumeration constant.
Here is an example with an enum whose constants represent the four
basic arithmetic operations, and whose eval
method performs the
operation:
public enum Operation { PLUS, MINUS, TIMES, DIVIDE; // Do arithmetic op represented by this constant double eval(double x, double y){ switch(this) { case PLUS: return x + y; case MINUS: return x - y; case TIMES: return x * y; case DIVIDE: return x / y; } throw new AssertionError("Unknown op: " + this); } }
This works fine, but it will not compile without the throw statement, which is not terribly pretty. Worse, you must remember to add a new case to the switch statement each time you add a new constant to Operation . If you forget, the eval method with fail, executing the aforementioned throw statement
There is another way give each enum constant a different behavior for some method that avoids these problems. You can declare the method abstract in the enum type and override it with a concrete method in each constant. Such methods are known as constant-specific methods. Here is the previous example redone using this technique:
public enum Operation { PLUS { double eval(double x, double y) { return x + y; } }, MINUS { double eval(double x, double y) { return x - y; } }, TIMES { double eval(double x, double y) { return x * y; } }, DIVIDE { double eval(double x, double y) { return x / y; } }; // Do arithmetic op represented by this constant abstract double eval(double x, double y); }
Here is a sample program that exercises the Operation
class. It takes two operands from the command line, iterates over all
the operations, and for each operation, performs the operation and
prints the resulting equation:
public static void main(String args[]) { double x = Double.parseDouble(args[0]); double y = Double.parseDouble(args[1]); for (Operation op : Operation.values()) System.out.printf("%f %s %f = %f%n", x, op, y, op.eval(x, y)); } $ java Operation 4 2 4.000000 PLUS 2.000000 = 6.000000 4.000000 MINUS 2.000000 = 2.000000 4.000000 TIMES 2.000000 = 8.000000 4.000000 DIVIDE 2.000000 = 2.000000
Constant-specific methods are reasonably sophisticated, and many programmers will never need to use them, but it is nice to know that they are there if you need them.
Two classes have been added to java.util
in support of enums:
special-purpose Set
and Map
implementations called
EnumSet
and EnumMap
.
EnumSet
is a high-performance
Set
implementation for enums. All of the members of an
enum set must be of the same enum type. Internally, it is represented by a
bit-vector, typically a single long
. Enum sets support iteration
over ranges of enum types. For example given the following enum
declaration:
enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }
you can iterate over the weekdays. The EnumSet
class
provides a static factory that makes it easy:
for (Day d : EnumSet.range(Day.MONDAY, Day.FRIDAY)) System.out.println(d);
Enum sets also provide a rich, typesafe replacement for traditional bit flags:
EnumSet.of(Style.BOLD, Style.ITALIC)
Similarly, EnumMap
is a high-performance Map
implementation for use with enum keys, internally implemented as an array.
Enum maps combine the richness and safety of the Map
interface
with speed approaching that of an array. If you want to map an enum to a
value, you should always use an EnumMap
in preference to an array.
The Card
class, above, contains a static
factory that returns a deck, but there is no way to get an individual card
from its rank and suit. Merely exposing the constructor would destroy the
singleton property (that only a single instance of each card is allowed to
exist). Here is how to write a static factory that preserves the singleton
property, using a nested EnumMap
:
private static Map<Suit, Map<Rank, Card>> table = new EnumMap<Suit, Map<Rank, Card>>(Suit.class); static { for (Suit suit : Suit.values()) { Map<Rank, Card> suitTable = new EnumMap<Rank, Card>(Rank.class); for (Rank rank : Rank.values()) suitTable.put(rank, new Card(rank, suit)); table.put(suit, suitTable); } } public static Card valueOf(Rank rank, Suit suit) { return table.get(suit).get(rank); }
The EnumMap
(table
) maps each suit to an
EnumMap
that maps each rank to a card. The lookup performed by the
valueOf
method is internally implemented as two array accesses,
but the code is much clearer and safer. In order to preserve the
singleton property, it is imperative that the constructor invocation in the
prototype deck initialization in Card
be replaced by a call to
the new static factory:
// Initialize prototype deck
static {
for (Suit suit : Suit.values())
for (Rank rank : Rank.values())
protoDeck.add(Card.valueOf(rank, suit)
);
}
It is also imperative that the initialization of table
be placed
above the initialization of protoDeck
, as the latter depends on the
former.
So when should you use enums? Any time you need a fixed set of
constants. That includes natural enumerated types (like the planets,
days of the week, and suits in a card deck) as well as other sets
where you know all possible values at compile time, such as choices on
a menu, rounding modes, command line flags, and the like. It is
not
necessary that the set of constants in an enum type stay
fixed for all time. The feature was specifically designed to allow
for binary compatible evolution of enum types.
发表评论
-
Spring声明式事务管理与配置详解
2015-08-18 09:00 01、Spring声明式事务配置的五种方式 前段时间对 ... -
Log4j的配置与使用详解
2015-08-18 08:44 7311、介绍 Log4j是Apache的一个开放源代码项目 ... -
Web.xml
2015-08-18 08:35 392web.xml文件详解 前言:一般的 ... -
Spring Filter
2015-08-18 08:23 4761、简介 Filter也称 ... -
springSecurity源码分析——DelegatingFilterProxy类的作用
2014-12-16 13:56 670http://www.cnblogs.com/hzhu ... -
spring data jpa 中的OpenEntityManagerInViewFilter 取代OpenSessionInViewFilter
2014-12-05 13:52 0http://blog.csdn.net/lzwglory/ ... -
servlet tomcat web.xml配备信息说明
2014-12-05 13:50 0servlet tomcat web.xml配置信息说明 ... -
Spring IntrospectorCleanupListener
2014-12-05 12:40 629spring中提供了一个名为 org.springfr ... -
Spring IOC容器实例化Bean的方式与RequestContextListener应用
2014-12-05 12:35 1035spring IOC容器实例化Be ... -
SpringBean的5种作用域
2014-12-05 12:33 760org.springframework.web.contex ... -
Lobback日志文件
2014-12-05 12:29 1144Logback是由log4j创始人Ceki Gülcü设计的 ... -
HTML Element
2012-08-05 17:16 9281. select 1) Clear Select O ... -
Prototype Study (转)
2012-08-05 16:49 760什么是Prototype Prototype 是由 S ... -
Prototype Element
2012-08-05 16:46 9031. select <select name=&q ... -
IE Firefox 一些组件的特殊处理
2012-07-29 09:04 8471、html alt 在IE下控件的alt属性使用赋值后,当 ... -
log4j 自动生成 appender
2011-05-04 21:55 1634一般log4j的配置是通过log4j.properties或x ... -
Java ASP Post
2011-03-06 20:32 1155用Java编写的模拟ASP Post请求写的一个上海的违章查询 ... -
Java Spring2.5 Remote Invoke HTTP Invoker
2011-03-06 20:16 2638近日,一个项目涉及到 ... -
Java Spring1.2 Remote Invoke HTTP Invoker
2011-02-25 09:12 1264近日,一个项目涉及到系统间接口调用,考虑到系统间用的都是jav ... -
File Encoding Converter
2009-11-13 16:52 1645在Java应用开发中,经常会遇到不同的开发人员的IDE设置的文 ...
相关推荐
选项Swift软件包,用于更强大的Enum类型。 目录介绍特征安装用法设置一个MappedValueRepresentable枚举使用MappedValueCollectionRepresented 使用MappedEnum类型的可编码枚举在ESet中使用OptionSet中的EnumSet 将...
常见的enum类型重定义的解决方法,清晰明了。
简单介绍了DNS和ENUM的原理及在IMS网络中的使用
enum枚举的方法
C++中枚举类型(enum)
opc enum 32_64安装包
Enum.doc Enum.docEnum.doc Enum.doc Enum.doc Enum.doc Enum.doc Enum.doc Enum.doc
用于枚举磁盘设备的 Enumdisk 示例
一个分析 enum 结构分析 源码资源
php-enum, PHP Enum实现灵感来自 SplEnum PHP enum 实现来自 SplEnum 为什么?首先,SplEnum 并不集成到PHP中,你必须单独安装它。使用 enum 而不是类常量提供了以下优点:你可以键入提示: function setAction(Ac
java enum详细教程。由浅入深,包括基本语法方面..很适合新手学习。/n各位看官。绝对超值。
enum.docx ,详细介绍了enum的用法,枚举用法在c#中比较常见,希望会有帮助哦
资源分类:Python库 所属语言:Python 资源全名:enum34-1.1.3-py2.py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
c#遍历枚举(ENUM)类型的方法,简单实用,适合c#初学者
Java enum的用法详解,可作为开发api
WPF中如何在XAML里绑定Enum的例子
博文“Java 语言中 Enum 类型的使用介绍”的源码。
C#与C调用C++,非托管,含struct调用及enum公用,完整项目,可直接编译或运行。 项目将所有工程的输出统一到Debug。 vs2015+Framework4.6,注意工程的配置。 所有东西自写,只是出于样例参考的作用,所以代码规范...
Laravel开发-enum PHP的枚举实现
simple_enum, 支持ActiveModel的简单 enum ( 包括验证和 i18n ) SimpleEnum 对于ActiveRecord和 ruby,低调的枚举像字段一样,给ActiveRecord和Mongoid模型( 为 Rails 4 构建) 带来了枚举功能。从 2.0版本开始,...