19 枚举类型 Enumerated
关键词enum可以将一组具名的值的有限集合创建为一种新的类型, 而这些具名的值可以作为常规的程序组件使用, 这是一种非常有用的功能
- 基本enum特性
enum Shrubbery {
GROUND, CRAWLING, HANGING
}
public class EnumClass {
public static void main(String[] args) throws Exception {
//values()方法遍历enum中所有的实例
for(Shrubbery s : Shrubbery.values()) {
//ordinal()返回实例在enum中唯一的序号(声明时的次序)
print(s + " oridinal: " + s.ordinal());
//enum实现了Comaparable接口, 所以具有compareTo接口
printnb(s.compareTo(Shrubbery.CRAWLING) + " ");
//enum自动提供了equals()方法和hashCode()方法
printnb(s.equals(Shrubbery.CRAWLING) + " ");
print(s == Shrubbery.CRAWLING);
//获取声明的enum名
print(s.getDeclaringClass());
print("------------");
}
}
}
导入enum
这是一个enum
public enum Spiciness {
NOT, MILD, MEDIUM, HOT, FLAMING
}
静态导入这个enum
import static enumerated.Spiciness.*;
public class Burrito {
Spiciness degree;
public Burrito(Spiciness degree) {
this.degree = degree;
}
public String toString() {
return "Burrito is " + degree;
}
public static void main(String[] args) throws Exception {
System.out.println(new Burrito(NOT));
System.out.println(new Burrito(HOT));
}
}
- 向enum中添加新方法
可以向enum中添加方法, 甚至main方法
public enum OZWitch {
WEST("west"),
NORTH("north"),
EAST("east"),
SOUTH("south");
//必须在最后一个实例的最后加一个分号
private String description;
//添加了一个每一个实例用一个字符串描述自身的构造器
private OZWitch(String description) {
this.description = description;
}
public String getDescription() { return this.description; }
public static void main(String[] args) {
for(OZWitch witch : OZWitch.values()) {
print(witch + ": " + witch.getDescription());
}
}
}
覆盖enum的方法
public enum SpaceShip {
COUT, CARGO, TRANSPORT, CRUISER, BATTLESHIP, MOTHERSHIP;
//覆盖toString()方法, 改变输出实例的格式
public String toString() {
//name()返回实例的名字, 即定义时全大写的形式
String id = name();
String lower = id.substring(1).toLowerCase();
//返回开头大写, 后面都是小写的形式
return id.charAt(0) + lower;
}
public static void main(String[] args) {
for(SpaceShip s : values()) {
System.out.println(s);
}
}
}
- 在switch中使用enum
enum Signal { GREEN, YELLOW, RED }
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch(color) {
case RED: color = Signal.GREEN;
break;
case GREEN: color = Signal.YELLOW;
break;
case YELLOW: color = Signal.RED;
}
}
}
enum中自动存储了每个实例的序号, 用switch读取enum实例的时候, 编译器会自动帮我们调用oridinal()获取它的序号值
- values()
enum Explore { HERE, THERE }
反编译后的Explore
Compiled from "Reflection.java"
final class enumerated.Explore extends java.lang.Enum<enumerated.Explore> {
public static final enumerated.Explore HERE;
public static final enumerated.Explore THERE;
static {};
public static enumerated.Explore[] values();
public static enumerated.Explore valueOf(java.lang.String);
}
values()方法是编译器向enum中添加的static方法, 如果你把enum实例向上转型成Enum, 就失去这个方法了
但是在Enum的Class里有一个getEnumConstants()方法, 可以获取实例
for(Enum en : e.getClass().getEnumConstants())
System.out.println(en);
- 实现, 而非继承
enum都继承自Enum, 所以不能再继承其他类, 只能实现接口
随机选取
下面是一个生成随机选取实例的例子
public class Enums {
private static Random rand = new Random(47);
public static <T extends Enum<T>> T random(Class<T> ec) {
return random(ec.getEnumConstants());
}
public static <T> T random(T[] values) {
return values[rand.nextInt(values.length)];
}
}
<T extends Enum<T>>表示T是Enum的一个实例, 将Class<T>作为参数, 就可以获取实例的数组
重载的从实例数组随机选取的方法就跟Enum类无关了
- 使用接口组织枚举
在一个接口的内部, 创建实现该接口的枚举, 以此将枚举分组
下面这些枚举代表不同的食物种类, 它们都实现了food接口, 可以向上转型为统一的food类型
public interface Food {
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS
}
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOD
}
}
可以像下面这样, 写一个枚举的枚举, 由于这些枚举都是实现了同一接口的子枚举, 可以将它们向上转型
为食物类型
public enum Course {
APPETIZER(Food.Appetizer.class),
MAINCOURSE(Food.MainCourse.class);
private Food[] values;
private Course(Class<? extends Food> kind) {
values = kind.getEnumConstants();
}
public Food randomSelection() {
return Enums.random(values);
}
}
取出每个枚举以及它包含的实例的时候, 可以转换为food类型
for(int i = 0;i < 5;i++) {
for(Course course : Course.values()) {
Food food = course.randomSelection();
System.out.println(food);
}
System.out.println("---");
}
或者直接把接口嵌套在一个枚举里面
public enum SecurityCategory {
//STOCK和BOND里面存储的是接口里面定义的两个枚举的实例
STOCK(Security.Stock.class),
BOND(Security.Bond.class);
private Security[] values;
SecurityCategory(Class<? extends Security> kind) {
values = kind.getEnumConstants();
}
interface Security {
enum Stock implements Security { SHORT, LONG, MARGIN }
enum Bond implements Security { MUNICIPAL, JUNK }
}
public Security randomSelection() {
return Enums.random(values);
}
public static void main(String[] args) {
for(int i = 0;i < 10;i++) {
SecurityCategory category =
Enums.random(SecurityCategory.class);
System.out.println(category.randomSelection());
}
}
}
- 使用EnumSet替代标志
将一种enum类型的一些实例放进EnumSet中
public class EnumSets {
public static void main(String[] args) throws Exception {
//noneof()创建一个空的EnumSet
//初始化用enum.class
EnumSet<AlarmPoints> points =
EnumSet.noneOf(AlarmPoints.class);
points.add(BATHROOM);
print(points);
points.addAll(EnumSet.of(START1, START2, KITCHEN));
print(points);
//加入整个enum
points = EnumSet.allOf(AlarmPoints.class);
print(points);
points.removeAll(EnumSet.of(START1, START2, KITCHEN));
print(points);
points = EnumSet.complementOf(points);
}
}
- EnumMap
EnumMap要求其中的键必须来自一个enum,
由于enum数量的限制, 所以EnumMap内部可以由数组实现
Command用了命令模式, 是一个只有一个方法的接口
interface Command { void action(); }
public class EnumMaps {
public static void main(String[] args) throws Exception {
//初始化也是用enum.class
EnumMap<AlarmPoints, Command> em =
new EnumMap<AlarmPoints, Command>(AlarmPoints.class);
em.put(KITCHEN, new Command() {
public void action() {
print("kitchen fire!");
}
});
em.put(BATHROOM, new Command() {
public void action() {
print("Bathroom alert!");
}
});
for(Map.Entry<AlarmPoints, Command> e : em.entrySet()) {
printnb(e.getKey() + ": ");
e.getValue().action();
}
try {
em.get(UTILITY);
} catch(Exception e) {
print(e);
}
}
}
每一个enum的实例可以在内部定义一些自己的行为,
在enum中定义一个抽象方法, 然后为每个实例实现这个方法
public enum ConstantSpecificMethod {
DATE_TIME {
String getInfo() {
return DateFormat.getDateInstance().format(new Date());
}
},
CLASSPATH {
String getInfo() {
return System.getProperty("classpath");
}
},
VERSION {
String getInfo() {
return System.getProperty("java.version");
}
};
abstract String getInfo();
public static void main(String[] args) {
for(ConstantSpecificMethod csm : values())
System.out.println(csm.getInfo());
}
}
看上去实例就像是enum的子类一样, 用这种方式实现了多态, 实际上并不是
enum的实例只是enum的static final对象, 它不能访问enum中的非静态成员, 所实现的抽象方法所能实现的方法也是有限的,
这些方法只能是常量相关的
下面是一个enum反编译后的结果
abstract class enumerated.LikeClasses extends java.lang.Enum<enumerated.LikeClasses> {
public static final enumerated.LikeClasses WINKEN;
public static final enumerated.LikeClasses BLINKEN;
public static final enumerated.LikeClasses NOD;
static {};
abstract void behavior();
public static enumerated.LikeClasses[] values();
public static enumerated.LikeClasses valueOf(java.lang.String);
enumerated.LikeClasses(java.lang.String, int, enumerated.LikeClasses);
}
枚举中实例的方法, 也可以覆盖掉enum中已有的方法
使用enum职责链
职责链设计模式是为了解决一个问题, 把不同的解决方案放到一起形成一个职责链, 当有问题的请求来时, 逐一执行链上每一环, 直
到解决问题
下面是一个邮局处理信件的例子
//每一个Mail对象代表一封待解决的邮件
class Mail {
//这每一个enum代表一种对信件处理的方式, 把它们串起来就是一个职责链
//每一次尝试都可以看作一个策略, 只有当策略返回YES, OK表示解决时, 完成职责链
enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5}
enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4}
enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4}
enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6}
enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5}
GeneralDelivery generalDelivery;
Scannability scannability;
Readability readability;
Address address;
ReturnAddress returnAddress;
static long counter = 0;
long id = counter++;
public String toString() { return "Main " + id; }
public String details() {
return toString() +
", General Delivery: " + generalDelivery +
", Address Scannability: " + scannability +
", Address Readability: " + readability +
", Address Address: " + address +
", Return address: " + returnAddress;
}
//随机产生一个Mail对象, 里面为每一种enum随机分配一个实例
public static Mail randomMail() {
Mail m = new Mail();
m.generalDelivery = Enums.random(GeneralDelivery.class);
m.scannability = Enums.random(Scannability.class);
m.readability = Enums.random(Readability.class);
m.address = Enums.random(Address.class);
m.returnAddress = Enums.random(ReturnAddress.class);
return m;
}
//Mail的迭代器, 每次迭代产生是上面的随机邮件
public static Iterable<Mail> generator(final int count) {
return new Iterable<Mail>() {
int n = count;
public Iterator<Mail> iterator() {
return new Iterator<Mail>() {
public boolean hasNext() { return n-- > 0; }
public Mail next() { return randomMail(); }
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
}
public class PostOffice {
//用MailHandler进行每个实例的尝试, 当有一种实例返回成功的结果, 就返回true, 表示邮件被成功解决
enum MailHandler {
GENERAL_DELIVERY {
boolean handle(Mail m) {
switch(m.generalDelivery) {
case YES:
print("Using general delivery for " + m);
return true;
default:
return false;
}
}
},
MACHINE_SCAN {
boolean handle(Mail m) {
switch(m.scannability) {
case UNSCANNABLE: return false;
default: {
switch (m.address) {
case INCORRECT: return false;
default:
print("Delivering " + m + " automatically");
return true;
}
}
}
}
},
VISUAL_INSPECTION {
boolean handle(Mail m) {
switch(m.readability) {
case ILLEGIBLE: return false;
default: {
switch (m.address) {
case INCORRECT: return false;
default:
print("Delivering " + m + " normally");
return true;
}
}
}
}
},
RETURN_TO_SENDER {
boolean handle(Mail m) {
switch(m.returnAddress) {
case MISSING: return false;
default: {
switch (m.address) {
case INCORRECT: return false;
default:
print("Returning " + m + " to sender");
return true;
}
}
}
}
};
abstract boolean handle(Mail m);
}
//遍历enum MailHandler的每种尝试, 里面可以调用不同的handle方法
static void handle(Mail m) {
for(MailHandler handler : MailHandler.values())
if(handler.handle(m))
return;
print(m + " is a dead letter");
}
//随机产生10个Mail, 对每个Mail, 执行一次职责链
public static void main(String[] args) throws Exception {
for(Mail mail : Mail.generator(10)) {
print(mail.details());
handle(mail);
print("********");
}
}
}
使用enum的状态机
下面用了一个自动售货机的例子来表示一个状态机
定义个一个输入enum, Input每个实例具有一个值, 代表钱的价值或者商品价值
//用一个enum将这些输入状态归类
enum Category {
//不同种类的钱
MONEY(NICKEL, DIME, QUARTER, DOLLAR),
//不同种类的商品
ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP),
//结束交易
QUIT_TRANSACTION(ABORT_TRANSACTION),
//结束整个状态
SHUT_DOWN(STOP);
//每个分类实例中放置的Input实例
private Input[] values;
//多个参数来初始化分类实例
Category(Input... types) { values = types; }
//分类eumMap, key表示一个Input, value表示它所属的分类实例
private static EnumMap<Input, Category> categories =
new EnumMap<Input, Category>(Input.class);
static {
//每个分类实例下的Input实例数组, 作为key, 分类实例作为value, 构建map
for(Category c : Category.class.getEnumConstants())
for(Input type : c.values)
categories.put(type,c);
}
//根据Input实例, 返回所属的分类
public static Category categorize(Input input) {
return categories.get(input);
}
}
//上面这个分类就是得到一个根据输入的实例, 得到输入类型分类的功能
//下面这个就是自动售货机的状态机
public class VendingMachine {
//State enum, 表示当前售货机的状态, RESTING为原始状态
private static State state = State.RESTING;
//表示售货机中收到的钱数
private static int amount = 0;
//表示选择的商品
private static Input selection = null;
enum StateDuration { TRANSIENT; }
//State状态enum, 为每一状态定义next()方法, 确定下一个状态, 以及售贩等操作
enum State {
//原始状态
RESTING {
void next(Input input) {
//根据输入所属类型来进行不同操作
switch(Category.categorize(input)) {
//钱, 客人给的钱, 把数额加到售货机中收到的钱中, 转为继续收钱状态
case MONEY:
amount += input.amount();
state = ADDING_MONEY;
break;
//退出售货机, 转为结束状态
case SHUT_DOWN:
state = TERMINAL;
default:
}
}
},
//继续收钱状态
ADDING_MONEY {
void next(Input input) {
switch(Category.categorize(input)) {
//继续收钱
case MONEY:
amount += input.amount();
break;
//选择商品, 如果收的钱不够商品价格, 输出钱不够, 否则转换为商品结算状态
case ITEM_SELECTION:
selection = input;
if(amount < selection.amount())
print("Insufficient money for " + selection);
else state = DISPENSING;
break;
//放弃交易, 进入找钱状态
case QUIT_TRANSACTION:
state = GIVING_CHANGE;
break;
//退出售货机, 转为结束状态
case SHUT_DOWN:
state = TERMINAL;
default:
}
}
},
//结算商品状态
DISPENSING(StateDuration.TRANSIENT) {
//从收到的钱中扣除商品价格, 进入找钱状态
void next() {
print("here is your " + selection);
amount -= selection.amount();
state = GIVING_CHANGE;
}
},
//找钱状态
GIVING_CHANGE(StateDuration.TRANSIENT) {
void next() {
//收到的钱还有剩, 找钱, 并清空收到的钱, 转换为初始状态
if(amount > 0) {
print("Your change: " + amount);
amount = 0;
}
state = RESTING;
}
},
//结束状态
TERMINAL {
void output() { print("Halted"); };
};
//每个状态实例是否是一个暂时性状态, 如果是暂时性状态, 处理完状态后, 不需要输入, 直接跳转到下一个状态
private boolean isTransient = false;
State() {}
//暂时性状态初始化
State(StateDuration trans) {
isTransient = true;
}
//非暂时性状态, 状态改变需要输入
void next(Input input) {
throw new RuntimeException();
}
//暂时性状态, 状态改变不需要输入
void next() {
throw new RuntimeException();
}
//输出售货机中收到的钱
void output() { print("amount: "+amount); }
}
//根据输入自动运行售货机
static void run(Generator<Input> gen) {
//遇到结束状态, 推出
while(state != State.TERMINAL) {
Input in = gen.next();
System.out.println("Input: " + in);
//获取输入并根据输入执行当前状态的方法, 调转至下一状态
state.next(in);
//从下一状态开始连续的暂时性状态, 直接执行转换下去, 直到遇到非暂时性状态
while(state.isTransient)
state.next();
//输出钱数
state.output();
}
}
public static void main(String[] args) throws Exception {
//从文件中按";"分隔, 读取一组Input实例, 然后运行这些实例, 查看售货机的运行状态
Generator<Input> gen = new RandomInputGenerator();
gen = new FileInputGenerator("VendingMachingInput.txt");
run(gen);
}
}
class RandomInputGenerator implements Generator<Input> {
public Input next() { return Input.randomSelection(); }
}
class FileInputGenerator implements Generator<Input> {
private Iterator<String> input;
public FileInputGenerator(String fileName) {
input = new TextFile(fileName,";").iterator();
}
public Input next() {
if(!input.hasNext())
return null;
return Enum.valueOf(Input.class, input.next().trim());
}
}
/*
VendingMachingInput.txt
QUARTER; QUARTER; QUARTER; CHIPS;
DOLLAR; DOLLAR; TOOTHPASTE;
QUARTER; DIME; ABORT_TRANSACTION;
QUARTER; DIME; SODA;
QUARTER; DIME; NICKEL; SODA;
ABORT_TRANSACTION;
STOP;
*/
- 多路分发
执行的操作包含了不止一个类型未知对象的操作, 要使用多路分发
两路分发, 必须要有两个方法调用, 第一个方法调用决定第一个未知类型, 第二个调用决定第二个未知类型
下面是一个石头剪刀布的两路分发
public enum Outcome {
WIN, LOSE, DRAW
}
//Item是这几种类型的接口, 被用作多路分发
interface Item {
Outcome compete(Item it);
Outcome eval(Paper p);
Outcome eval(Scissors s);
Outcome eval(Rock r);
}
class Paper implements Item {
//第一个方法compete()决定第一个类型, 完成第一次分发, 即发起比较的类型, 其中的参数Item是第二个类型,
//把发起比较的类型当作第二个类型的参数this, 放在第二个方法中
public Outcome compete(Item it) { return it.eval(this); }
//第二个方法eval()决定第二个类型, 完成第二次分发, 表示被比较的类型, 它的参数是在第一次分发中确定的
//发起比较的类型, 那么可以根据具体的参数类型重载这个方法返回比较结果
public Outcome eval(Paper p) { return DRAW; }
public Outcome eval(Scissors s) { return WIN; }
public Outcome eval(Rock r) { return LOSE; }
public String toString() { return "Paper"; }
}
class Scissors implements Item {
public Outcome compete(Item it) { return it.eval(this); }
public Outcome eval(Paper p) { return LOSE; }
public Outcome eval(Scissors s) { return DRAW; }
public Outcome eval(Rock r) { return WIN; }
public String toString() { return "Scissors"; }
}
class Rock implements Item {
public Outcome compete(Item it) { return it.eval(this); }
public Outcome eval(Paper p) { return WIN; }
public Outcome eval(Scissors s) { return LOSE; }
public Outcome eval(Rock r) { return DRAW; }
public String toString() { return "Rock"; }
}
public class RoShambo1 {
static final int SIZE = 20;
private static Random rand = new Random(47);
public static Item newItem() {
switch(rand.nextInt(3)) {
default:
case 0: return new Scissors();
case 1: return new Paper();
case 2: return new Rock();
}
}
public static void match(Item a, Item b) {
System.out.println(a + " vs. " + b + ": " + a.compete(b));
}
public static void main(String[] args) throws Exception {
for(int i = 0;i < SIZE;i++)
match(newItem(), newItem());
}
}
这个例子没有用到enum, 而且enum是不能作为真正的类型的
下面是使用enum进行多路分发的方法
RoShamBo2.java
//这个enum的每个实例代表一种类型, 石头, 剪刀, 或布, 它们每个都存储了, 对石头, 对剪刀, 对布的胜负结果
public enum RoShamBo2 implements Competitor<RoShamBo2>{
PAPER(DRAW, LOSE, WIN),
SCISSORS(WIN, DRAW, LOSE),
ROCK(LOSE, WIN, DRAW);
//对剪刀, 对石头, 对布的结果
private Outcome vPaper, vScissors, vRock;
private RoShamBo2(Outcome paper, Outcome scissors, Outcome rock) {
this.vPaper = paper;
this.vScissors = scissors;
this.vRock = rock;
}
//去和另一个RoShamBo2实例比较, 根据参数是哪个实例, 返回this对这个实例类型的结果
public Outcome compete(RoShamBo2 it) {
switch(it) {
default:
case PAPER: return vPaper;
case SCISSORS: return vScissors;
case ROCK: return vRock;
}
}
public static void main(String[] args) {
RoShamBo.play(RoShamBo2.class, 20);
}
}
RoShamBo.java
public class RoShamBo {
public static <T extends Competitor<T>>
void match(T a, T b) {
System.out.println(a + " vs. " + b + ": " + a.compete(b));
}
public static <T extends Enum<T> & Competitor<T>>
void play(Class<T> rsbClass, int size) {
for(int i = 0;i < size;i++)
match(Enums.random(rsbClass),Enums.random(rsbClass));
}
}
Competitor.java
//这个泛型只能存那个类本身
public interface Competitor<T extends Competitor<T>> {
Outcome compete(T competitor);
}
下面是一个使用EnumMap实现多路分发的例子
public enum RoShamBo5 implements Competitor<RoShamBo5> {
PAPER, SCISSORS, ROCK;
//这里一个EnumMap, key存发起比较的实例, value是一个EnumMap, 它的key是被比较的实例, value是比较结果
//它是一个static成员, 已经预先存储好所有类型的所有行为以及产生的所有结果
static EnumMap<RoShamBo5,EnumMap<RoShamBo5,Outcome>> table =
new EnumMap<RoShamBo5,EnumMap<RoShamBo5,Outcome>>(RoShamBo5.class);
static {
for(RoShamBo5 it : RoShamBo5.values())
table.put(it, new EnumMap<RoShamBo5,Outcome>(RoShamBo5.class));
initRow(PAPER,DRAW,LOSE,WIN);
initRow(SCISSORS,WIN,DRAW,LOSE);
initRow(ROCK,LOSE,WIN,DRAW);
}
static void initRow(RoShamBo5 it, Outcome vPaper, Outcome vScissors, Outcome vRock) {
EnumMap<RoShamBo5, Outcome> row =
table.get(it);
row.put(RoShamBo5.PAPER,vPaper);
row.put(RoShamBo5.SCISSORS,vScissors);
row.put(RoShamBo5.ROCK,vRock);
}
//根据EnumMap的结果, 当前实例this作为EnumMap的第一维key被get后, 得到该类型所对应的行为信息, 完成第一次分发
//第二次get被比较的实例it, 得到第二次分发后的信息
public Outcome compete(RoShamBo5 it) {
return table.get(this).get(it);
}
public static void main(String[] args) {
RoShamBo.play(RoShamBo5.class, 20);
}
}
19 枚举类型 Enumerated相关推荐
- thinking-in-java(19)枚举类型
[0]开场白 1)关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用: 2)所有的枚举类都继承自 Enum,通过 enumClass.getSu ...
- enum枚举类型用法
文章目录 1. 枚举类型和枚举变量 1.1 枚举类型的定义和声明 1.2 枚举变量的定义和声明 2. 枚举变量和枚举常量的关联对应 3. 枚举类型和变量的应用 3.1 作为判断语句中的逻辑 3.2 一 ...
- 浅析枚举类型(Enumerated types)
枚举类型定义了一系列有序值的集合.枚举变量就是从这个既定的集合中取某个值.集合中的有序值可以称为元素,元素一般从0开始索引(也就是元素的顺序号). 定义一个枚举类型,采用以下的格式: type typ ...
- C++ 学习笔记(19)new/delete表达式、定位new、typeid、dynamic_cast、type_info、枚举类型、成员函数指针、union、位域、volatile限定符、链接指示
C++ 学习笔记(19)new/delete表达式.定位new.typeid.dynamic_cast.type_info.枚举类型.成员函数指针.union.位域.volatile限定符.链接指示 ...
- C++ Primer 5th笔记(chap 19 特殊工具与技术)枚举类型
1. 枚举类型(enumeration) 将一组整型常量组织在一起. 1.1 限定作用域 的 枚 举 类 型( scoped enumeration) 关 键 字 enum class ( enum ...
- 《Java SE实战指南》06-08:枚举类型(Enumerated types)
内容导航: 前言 1.定义 2.使用场景 3.高阶应用 前言 在现实场景中,我们发现某类事物包含的名称.范围和含义是有限的,都可以列举出来. 方向:北.南.东.西: 季节:春季.夏季.秋季.冬季: 月 ...
- 理解Java枚举类型
(参考资料:深入理解java enum) 1.原理:对编译后的class文件javap反编译可以看出,定义的枚举类继承自java.lang.Enum抽象类且通过public static final定 ...
- 将不确定变为确定~整形变量是否可以进行位运算(像枚举类型一样)
回到目录 如果您看到这个题目,觉得有点怪,那说明你是一个高人,最起码比我高的多,呵呵. 前几天做了一个公用后台管理系统的项目,其中有一个地方涉及到权限管理的,即为每一个按钮赋一个权限,然后它权限汇总到 ...
- 在java中关于枚举类型的特性_java枚举类型小结
JDK5.0之前,我们一般选择使用 interface 来保存常量组,以此来弥补 JDK 中没有枚举类型的缺陷,从JDK5.0开始,Sun引进了一个全新的关键字 enum 来定义一个枚举类.同inte ...
- DELPHI设置枚举类型size
delphi枚举类型长度默认为2个字节(单字),而在C中枚举为4个字节(双字),如果需要跨这两个平台编程,传输结构时会由于数据长度不一造成灾难. 经过查找资料,原来delphi可以通过{$Z+} {$ ...
最新文章
- 关于Qt Designer程序/UI文件打开未响应的解决方法
- malware分析视频
- mysql组件化_组件化开发和模块化开发概念辨析
- 将项目依赖也打到jar包中
- 计算机专业伦理总结,《计算机伦理学》节译实践报告
- 深入理解Redis系列之SpringBoot集成Redis
- 百度网盘svip下载时显示下载请求中无下载速度
- 适合练手的10个前端实战项目(附视频+源码)
- 蓝桥杯官网试题 欧拉的鸡蛋
- Red5流媒体服务器搭建
- 基于python的垃圾分类程序,提供数据集(pytorch开发)
- 难倒高手了,c语言枚举end的作用是什么?
- EChart自定义饼图颜色
- 近期工作心得(总结篇)
- 《程序员》12月精彩内容:双11技术决战
- 小学生心算CAI系统
- Oracle 使用xtts升级11g-to-19c
- 外贸:圣诞新年祝福语语
- 液晶屏循环显示单色 液晶屏检测程序
- Node.js(六)express 框架 使用
热门文章
- html如何发送语音,浏览器实现HTML5发送语音功能
- 微信平台商户开通证书相关问题盘点
- Android设备上px(像素)、dpi(像素密度)、dip(密度无关像素)之间的关系
- 感冒为什么会流鼻涕?
- js表单提交的三种方式
- win10调整鼠标滚轮方向
- 大数据私房菜--Hadoop完全分布式安装
- java int64 类型_详解 Java 的八大基本类型,写得非常好!
- mac下Cornerstone显示日志问题 Cound not contact repository to read the latest log entries
- 牛客网刷题记录(3)组合逻辑