「java枚举怎么定义属性」java 枚举定义

博主:adminadmin 2022-12-27 14:27:12 82

今天给各位分享java枚举怎么定义属性的知识,其中也会对java 枚举定义进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

枚举的属性和方法

  枚举在Java中是一个类 ,代表着类的一一列举。要想知道枚举具体的使用首先要先知道它的具体的 属性 和 方法 才可以。虽然说我们在实际应用中很少去关注它的属性和方法,而是更多的关注它的 特性 ,利用它本身的特性去满足各种有意思的场景。

 由于上篇内容讲了我们自定义的枚举其实经过编译之后,实际继承的是lang包下的Enum类。虽然我们自定义的枚举类中可能存在不定义私有属性的情况,但继承的Enum类中自身就带有着两个属性,name属性、和ordinal属性。Enum类的源码

 name为我们枚举值的名称,而ordinal这个词的意思是“序数”或者说“有顺序的”,其实就是序数。我们知道枚举所代表的就是包含一个以上枚举值的集合,既然是集合它就是有顺序的,而大多数我们使用的时候往往忽略了它的序数这个属性,似乎忘了枚举是枚举这件事了。

 枚举中的序号是根据我们的枚举中显示的顺序决定的,其实是是语法糖转换时初始化枚举值时决定了枚举值的序数,枚举中,第一个枚举值的序数总是小于后面枚举值的序数,且序数是从0开始的。

 接着上面讲的序数ordinal,针对序数我们先讲枚举的values()方法。

作为一个枚举值的集合,所必须要有的操作肯定是遍历,这也是静态常量所没有的支持的。values()其实就是获取我们枚举值的数组:

 虽然我们自定义的枚举类是可以使用这个方法的,但继承的Enum类却没有这个方法,其实values()这个方法是很特殊的一个方法,之前说过枚举是一种语法糖,在它真正编译后,就会产生values()这个方法,所以我们自定义的枚举类是可以使用这个方法的,而且values()方法所返回的其实是一个浅拷贝;

 前面说到枚举有两个属性,name和ordinal,但实际上枚举只提供了根据name来获取具体枚举值的方法,却没有提供根据ordinal来获取具体枚举值的方法,但是values()方法也算是另外一种弥补了,根据values()得到的数据再根据ordinal序数获取具体的枚举值其实也是一样的效果。valueOf()方法就是那个根据name获取具体枚举值的方法,使用案例:

可选姿势为两种,一参和两参,具体看案例。

Java:这里的枚举常量是如何定义的呢?

枚举(从JDK1.5开始有)

用于代表”实例已经固定“的类,而且定义时就必须在【第一行】创建初始化并列出来。

语法格式:

修饰符 enum 枚举名{

//立即在第一行列出该枚举的所有实例。

}

—— 修饰符 可以是 public | 省略 | abstract | final。 abstract与final必须出现其中一个。

—— 枚举的构造器只能用private修饰。

—— 枚举类的实例必须在第一行显式的列出。

所有的枚举都有一个values()方法,返回枚举实例

switch(byte|short|char|int|String|枚举)

●有了枚举之后,它的实例已经创建出来了,只需要用它们就行了。

●枚举可以有Field,方法,构造器(只能是private修饰),初始化块,内部类。

列出枚举值,并不是简单的定义几个枚举值的变量名。

而是调用枚举类的构造器来创建相应的实例。

定义枚举的方法时要非常小心,

●包含抽象方法的枚举类

●枚举可以实现接口。

A。实现接口,并直接实现所有的抽象方法。

此时枚举类不再是抽象枚举了。

B。实现接口,但并不直接实现抽象方法。

此时枚举类就只能是抽象枚举类。

java中的枚举类型怎么定义?

Enum作为Sun全新引进的一个关键字,看起来很象是特殊的class, 它也可以有自己的变量,可以定义自己的方法,可以实现一个或者多个接口。 当我们在声明一个enum类型时,我们应该注意到enum类型有如下的一些特征。

1.它不能有public的构造函数,这样做可以保证客户代码没有办法新建一个enum的实例。

2.所有枚举值都是public , static , final的。注意这一点只是针对于枚举值,我们可以和在普通类里面定义 变量一样定义其它任何类型的非枚举变量,这些变量可以用任何你想用的修饰符。

3.Enum默认实现了java.lang.Comparable接口。

4.Enum覆载了了toString方法,因此我们如果调用Color.Blue.toString()默认返回字符串”Blue”.

5.Enum提供了一个valueOf方法,这个方法和toString方法是相对应的。调用valueOf(“Blue”)将返回Color.Blue.因此我们在自己重写toString方法的时候就要注意到这一点,一把来说应该相对应地重写valueOf方法。

6.Enum还提供了values方法,这个方法使你能够方便的遍历所有的枚举值。

7.Enum还有一个oridinal的方法,这个方法返回枚举值在枚举类种的顺序,这个顺序根据枚举值声明的顺序而定,这里Color.Red.ordinal()返回0。

了解了这些基本特性,我们来看看如何使用它们。

1.遍历所有有枚举值. 知道了有values方法,我们可以轻车熟路地用ForEach循环来遍历了枚举值了。

for (Color c: Color.values())

System.out.println(“find value:” + c);

2.在enum中定义方法和变量,比如我们可以为Color增加一个方法随机返回一个颜色。

public enum Color {

Red,

Green,

Blue;

/*

*定义一个变量表示枚举值的数目。

*(我有点奇怪为什么sun没有给enum直接提供一个size方法).

*/

private static int number = Color.values().length ;

/**

* 随机返回一个枚举值

@return a random enum value.

*/

public static Color getRandomColor(){

long random = System.currentTimeMillis() % number;

switch ((int) random){

case 0:

return Color.Red;

case 1:

return Color.Green;

case 2:

return Color.Blue;

default : return Color.Red;

}

}

}

可以看出这在枚举类型里定义变量和方法和在普通类里面定义方法和变量没有什么区别。唯一要注意的只是变量和方法定义必须放在所有枚举值定义的后面,否则编译器会给出一个错误。

3.覆载(Override)toString, valueOf方法

前面我们已经知道enum提供了toString,valueOf等方法,很多时候我们都需要覆载默认的toString方法,那么对于enum我们怎么做呢。其实这和覆载一个普通class的toString方法没有什么区别。

….

public String toString(){

switch (this){

case Red:

return "Color.Red";

case Green:

return "Color.Green";

case Blue:

return "Color.Blue";

default:

return "Unknow Color";

}

}

….

这时我们可以看到,此时再用前面的遍历代码打印出来的是

Color.Red

Color.Green

Color.Blue

而不是

Red

Green

Blue.

可以看到toString确实是被覆载了。一般来说在覆载toString的时候我们同时也应该覆载valueOf方法,以保持它们相互的一致性。

4.使用构造函数

虽然enum不可以有public的构造函数,但是我们还是可以定义private的构造函数,在enum内部使用。还是用Color这个例子。

public enum Color {

Red("This is Red"),

Green("This is Green"),

Blue("This is Blue");

private String desc;

Color(String desc){

this.desc = desc;

}

public String getDesc(){

return this.desc;

}

}

这里我们为每一个颜色提供了一个说明信息, 然后定义了一个构造函数接受这个说明信息。

要注意这里构造函数不能为public或者protected, 从而保证构造函数只能在内部使用,客户代码不能new一个枚举值的实例出来。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。

5.实现特定的接口

我们已经知道enum可以定义变量和方法,它要实现一个接口也和普通class实现一个接口一样,这里就不作示例了。

6.定义枚举值自己的方法。

前面我们看到可以为enum定义一些方法,其实我们甚至可以为每一个枚举值定义方法。这样,我们前面覆载 toString的例子可以被改写成这样。

public enum Color {

Red {

public String toString(){

return "Color.Red";

}

},

Green {

public String toString(){

return "Color.Green";

}

},

Blue{

public String toString(){

return "Color.Blue";

}

};

}

从逻辑上来说这样比原先提供一个“全局“的toString方法要清晰一些。

总的来说,enum作为一个全新定义的类型,是希望能够帮助程序员写出的代码更加简单易懂,个

人觉得一般也不需要过多的使用enum的一些高级特性,否则就和简单易懂的初衷想违背了。

java 枚举enum定义的方法与位置。

可以的,枚举的定义是这样的

public enum SEX{

MEN,WOMEN;

}

在其它类中引用枚举非常简单,可以向以前使用的java中的常量一样使用。

SEX.MEN或SEX.WOMEN

枚举和一般的类是一样的,有一个好处就是你使用的时候不用创建对象了,java帮我们创建好了。当然,在枚举里面也可以定义方法,建议你看一下这方面的书籍。

enum在java中是什么意思

Enum 类型的介绍

枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中。而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义相似。不过相比较常量类型,枚举类型可以为申明的变量提供更大的取值范围。

举个例子来说明一下,如果希望为彩虹描绘出七种颜色,你可以在 Java 程序中通过常量定义方式来实现。

清单 1. 常量定义

Public static class RainbowColor { 

    

    // 红橙黄绿青蓝紫七种颜色的常量定义

    public static final int RED = 0; 

    public static final int ORANGE = 1; 

    public static final int YELLOW = 2; 

    public static final int GREEN = 3; 

    public static final int CYAN = 4; 

    public static final int BLUE = 5; 

    public static final int PURPLE = 6; 

 }

使用的时候,你可以在程序中直接引用这些常量。但是,这种方式还是存在着一些问题。

类型不安全

由于颜色常量的对应值是整数形,所以程序执行过程中很有可能给颜色变量传入一个任意的整数值,导致出现错误。

没有命名空间

由于颜色常量只是类的属性,当你使用的时候不得不通过类来访问。

一致性差

因为整形枚举属于编译期常量,所以编译过程完成后,所有客户端和服务器端引用的地方,会直接将整数值写入。这样,当你修改旧的枚举整数值后或者增加新的枚举值后,所有引用地方代码都需要重新编译,否则运行时刻就会出现错误。

类型无指意性

由于颜色枚举值仅仅是一些无任何含义的整数值,如果在运行期调试时候,你就会发现日志中有很多魔术数字,但除了程序员本身,其他人很难明白其奥秘。

如何定义 Enum 类型

为了改进 Java 语言在这方面的不足弥补缺陷,5.0 版本 SDK 发布时候,在语言层面上增加了枚举类型。枚举类型的定义也非常的简单,用 enum 关键字加上名称和大括号包含起来的枚举值体即可,例如上面提到的彩虹颜色就可以用新的 enum 方式来重新定义:

enum RainbowColor { RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE }

从上面的定义形式来看,似乎 Java 中的枚举类型很简单,但实际上 Java 语言规范赋予枚举类型的功能非常的强大,它不仅是简单地将整形数值转换成对象,而是将枚举类型定义转变成一个完整功能的类定义。这种类型定义的扩展允许开发者给枚举类型增加任何方法和属性,也可以实现任意的接口。另外,Java 平台也为 Enum 类型提供了高质量的实现,比如默认实现 Comparable 和 Serializable 接口,让开发者一般情况下不用关心这些细节。

回到本文的主题上来,引入枚举类型到底能够给我们开发带来什么样好处呢?一个最直接的益处就是扩大 switch 语句使用范围。5.0 之前,Java 中 switch 的值只能够是简单类型,比如 int、byte、short、char, 有了枚举类型之后,就可以使用对象了。这样一来,程序的控制选择就变得更加的方便,看下面的例子:

清单 2. 定义 Enum 类型

// 定义一周七天的枚举类型

 public enum WeekDayEnum { Mon, Tue, Wed, Thu, Fri, Sat, Sun } 

 // 读取当天的信息

 WeekDayEnum today = readToday(); 

 

 // 根据日期来选择进行活动

 switch(today) { 

  Mon: do something; break; 

  Tue: do something; break; 

  Wed: do something; break; 

  Thu: do something; break; 

  Fri: do something; break; 

  Sat: play sports game; break; 

  Sun: have a rest; break; 

 }

对于这些枚举的日期,JVM 都会在运行期构造成出一个简单的对象实例一一对应。这些对象都有唯一的 identity,类似整形数值一样,switch 语句就根据此来进行执行跳转。

如何定制 Enum 类型

除了以上这种最常见的枚举定义形式外,如果需要给枚举类型增加一些复杂功能,也可以通过类似 class 的定义来给枚举进行定制。比如要给 enum 类型增加属性,可以像下面这样定义:

清单 3. 定制枚举类型

// 定义 RSS(Really Simple Syndication) 种子的枚举类型

 public enum NewsRSSFeedEnum { 

    // 雅虎头条新闻 RSS 种子

    YAHOO_TOP_STORIES(""), 

    

    //CBS 头条新闻 RSS 种子

    CBS_TOP_STORIES(""), 

    

    // 洛杉矶时报头条新闻 RSS 种子

    LATIMES_TOP_STORIES(""); 

        

    // 枚举对象的 RSS 地址的属性

    private String rss_url; 

        

    // 枚举对象构造函数

    private NewsRSSFeedEnum(String rss) { 

        this.rss_url = rss; 

    } 

        

    // 枚举对象获取 RSS 地址的方法

    public String getRssURL() { 

        return this.rss_url; 

    } 

 }

上面头条新闻的枚举类型增加了一个 RSS 地址的属性 , 记录头条新闻的访问地址。同时,需要外部传入 RSS 访问地址的值,因而需要定义一个构造函数来初始化此属性。另外,还需要向外提供方法来读取 RSS 地址。

如何避免错误使用 Enum

不过在使用 Enum 时候有几个地方需要注意:

enum 类型不支持 public 和 protected 修饰符的构造方法,因此构造函数一定要是 private 或 friendly 的。也正因为如此,所以枚举对象是无法在程序中通过直接调用其构造方法来初始化的。

定义 enum 类型时候,如果是简单类型,那么最后一个枚举值后不用跟任何一个符号;但如果有定制方法,那么最后一个枚举值与后面代码要用分号';'隔开,不能用逗号或空格。

由于 enum 类型的值实际上是通过运行期构造出对象来表示的,所以在 cluster 环境下,每个虚拟机都会构造出一个同义的枚举对象。因而在做比较操作时候就需要注意,如果直接通过使用等号 ( ‘ == ’ ) 操作符,这些看似一样的枚举值一定不相等,因为这不是同一个对象实例。

看下面的这个例子:

清单 4. 避免错误使用 Enum 示例

// 定义一个一周七天的枚举类型

 package example.enumeration.codes; 

 public enum WeekDayEnum { 

    Mon(1), Tue(2), Wed(3), Thu(4), Fri(5), Sat(6), Sun(7); 

    private int index; 

    WeekDayEnum(int idx) { 

        this.index = idx; 

    } 

    public int getIndex() { 

        return index; 

    } 

 }

// 客户端程序,将一个枚举值通过网络传递给服务器端

 package example.enumeration.codes; 

 import java.io.IOException; 

 import java.io.ObjectOutputStream; 

 import java.io.OutputStream; 

 import java.net.InetSocketAddress; 

 import java.net.Socket; 

 import java.net.UnknownHostException; 

 public class EnumerationClient { 

    public static void main(String... args) throws UnknownHostException, IOException { 

        Socket socket = new Socket(); 

  // 建立到服务器端的连接

        socket.connect(new InetSocketAddress("127.0.0.1", 8999)); 

    // 从连接中得到输出流

        OutputStream os = socket.getOutputStream(); 

        ObjectOutputStream oos = new ObjectOutputStream(os); 

  // 将星期五这个枚举值传递给服务器端

        oos.writeObject(WeekDayEnum.Fri); 

        oos.close(); 

        os.close(); 

        socket.close(); 

    } 

 } 

 // 服务器端程序,将从客户端收到的枚举值应用到逻辑处理中

 package example.enumeration.codes; 

 import java.io.*; 

 import java.net.ServerSocket; 

 import java.net.Socket; 

 public class EnumerationServer { 

    public static void main(String... args) throws IOException, ClassNotFoundException { 

        ServerSocket server = new ServerSocket(8999); 

  // 建立服务器端的网络连接侦听

        Socket socket = server.accept(); 

  // 从连接中获取输入流

        InputStream is = socket.getInputStream(); 

        ObjectInputStream ois = new ObjectInputStream(is); 

  // 读出客户端传递来的枚举值

        WeekDayEnum day = (WeekDayEnum) ois.readObject(); 

  // 用值比较方式来对比枚举对象

        if (day == WeekDayEnum.Fri) { 

            System.out.println("client Friday enum value is same as server's"); 

        } else if (day.equals(WeekDayEnum.Fri)) { 

            System.out.println("client Friday enum value is equal to server's"); 

        } else { 

            System.out.println("client Friday enum value is not same as server's"); 

        } 

        

  // 用 switch 方式来比较枚举对象

        switch (day) { 

            case Mon: 

                System.out.println("Do Monday work"); 

                break; 

            case Tue: 

                System.out.println("Do Tuesday work"); 

                break; 

            case Wed: 

                System.out.println("Do Wednesday work"); 

                break; 

            case Thu: 

                System.out.println("Do Thursday work"); 

                break; 

            case Fri: 

                System.out.println("Do Friday work"); 

                break; 

            case Sat: 

                System.out.println("Do Saturday work"); 

                break; 

            case Sun: 

                System.out.println("Do Sunday work"); 

                break; 

            default: 

                System.out.println("I don't know which is day"); 

                break; 

        } 

        

        ois.close(); 

        is.close(); 

        socket.close(); 

    } 

 }

打印结果如下:

client Friday enum value is same as server's

Do Friday work

通过程序执行结果,我们能够发现在分布式条件下客户端和服务端的虚拟机上都生成了一个枚举对象,即使看起来一样的 Fri 枚举值,如果使用等号‘ == ’进行比较的话会出现不等的情况。而 switch 语句则是通过 equal 方法来比较枚举对象的值,因此当你的枚举对象较复杂时候,你就需要小心 override 与比较相关的方法,防止出现值比较方面的错误。

Enum 相关工具类

JDK5.0 中在增加 Enum 类的同时,也增加了两个工具类 EnumSet 和 EnumMap,这两个类都放在 java.util 包中。EnumSet 是一个针对枚举类型的高性能的 Set 接口实现。EnumSet 中装入的所有枚举对象都必须是同一种类型,在其内部,是通过 bit-vector 来实现,也就是通过一个 long 型数。EnumSet 支持在枚举类型的所有值的某个范围中进行迭代。回到上面日期枚举的例子上:

enum WeekDayEnum { Mon, Tue, Wed, Thu, Fri, Sat, Sun }

你能够在每周七天日期中进行迭代,EnumSet 类提供一个静态方法 range 让迭代很容易完成:

for(WeekDayEnum day : EnumSet.range(WeekDayEnum.Mon, WeekDayEnum.Fri)) { 

     System.out.println(day); 

 }

打印结果如下:

Mon 

 Tue 

 Wed 

 Thu 

 Fri

EnumSet 还提供了很多个类型安全的获取子集的 of 方法,使你很容易取得子集:

EnumSetWeekDayEnum subset = EnumSet.of(WeekDayEnum.Mon, WeekDayEnum.Wed); 

      for (WeekDayEnum day : subset) { 

          System.out.println(day);  

      }

打印结果如下:

Mon 

 Wed

与 EnumSet 类似,EnumMap 也是一个高性能的 Map 接口实现,用来管理使用枚举类型作为 keys 的映射表,内部是通过数组方式来实现。EnumMap 将丰富的和安全的 Map 接口与数组快速访问结合到一起,如果你希望要将一个枚举类型映射到一个值,你应该使用 EnumMap。看下面的例子:

清单 5. EnumMap 示例

// 定义一个 EnumMap 对象,映射表主键是日期枚举类型,值是颜色枚举类型

 private static MapWeekDayEnum, RainbowColor schema = 

            new EnumMapWeekDayEnum, RainbowColor(WeekDayEnum.class); 

    

 static{ 

    // 将一周的每一天与彩虹的某一种色彩映射起来

    for (int i = 0; i  WeekDayEnum.values().length; i++) { 

        schema.put(WeekDayEnum.values()[i], RainbowColor.values()[i]); 

    } 

 } 

 System.out.println("What is the lucky color today?"); 

 System.out.println("It's " + schema.get(WeekDayEnum.Sat));

当你询问周六的幸运色彩时候,会得到蓝色:

清单 6. 运行结果

What is the lucky color today?

It's BLUE

结束语

Enum 类型提出给 JAVA 编程带了了极大的便利,让程序的控制更加的容易,也不容易出现错误。所以在遇到需要控制程序流程时候,可以多想想是否可以利用 enum 来实现。

java怎么定义枚举

在Java中,枚举(enum)与类(class)、接口(interface)属于同一个级别。

使用枚举的Java程序:

public class Main {

public static void main(String[] args) {

Week w = Week.Monday;

System.out.println(w);

}

}

//定义枚举

enum Week {

Sunday,

Monday,

Tuesday,

Wednesday,

Thursday,

Friday,

Saturday

}

运行测试:

Monday

关于java枚举怎么定义属性和java 枚举定义的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-12-27,除非注明,否则均为首码项目网原创文章,转载请注明出处。