<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Scott@JAVA

    Java, 一杯濃濃的咖啡伴你到深夜

    《Java 5.0 Tiger》Chapter 3

    Chapter 3. Enumerated Types

    3.1 Creating an Enum

    More often than not, you'll only need the basic enum functionality:

    public enum Grade { A, B, C, D, F, INCOMPLETE };

    The convention is to use all capital letters for enumerated type identifiers.

    "Grade" is used just like anyother Java type:

    public class Student {
        
    private String firstName;

        
    private String lastName;

        
    private Grade grade;

        
    public Student(String firstName, String lastName) {
            
    this.firstName = firstName;
            
    this.lastName = lastName;
        }


        
    public void assignGrade(Grade grade) {
            
    this.grade = grade;
        }


        
    public Grade getGrade() {
            
    return grade;
        }


    }

    Pretty basic, isn't it? The final piece is actually using this code in conjunction with the enum, as shown here:

        public void testGradeAssignment(PrintStream out) throws IOException {
            Student student1 
    = new Student("Brett""McLaughlin");
            Student student2 
    = new Student("Ben""Rochester");
            Student student3 
    = new Student("Dennis""Erwin");
            student1.assignGrade(Grade.B);
            student2.assignGrade(Grade.INCOMPLETE);
            student3.assignGrade(Grade.A);
        }

    Enums are classes
    Enums extend java.lang.Enum
    Enumerated types aren't integers
    Enums have no public constructor
    Enum values are public, static, and final
    Enum values can be compared with == or equals( )
    Enums implements java.lang.Comparable
    Enums override toString( )
    Enums provide a valueOf( ) method
    Enums define a final instance method named ordinal( )
    Enums define a values( ) method

    3.2 Declaring Enums Inline

    public class Downloader {
        
    public enum DownloadStatus {
            INITIALIZING, IN_PROGRESS, COMPLETE
        }
    ;
        
    // Class body
    }


    Nested enums are implicitly static.

    3.3 Iterating Over Enums

    Invoking the values( ) method on an enum returns an array of all the values in the type:

        public void listGradeValues(PrintStream out) throws IOException {
            Grade[] gradeValues 
    = Grade.values();
            
    for (Grade g : Grade.values()) {
                out.println(
    "Allowed value: '" + g + "'");
            }

        }

    3.4 Switching on Enums

    Prior to Java 1.4, switch only worked with int, short, char, and byte values. However, since enums have a finite set of values, Tiger adds switch support for them:

        public void testSwitchStatement(PrintStream out) throws IOException {
            StringBuffer outputText 
    = new StringBuffer(student1.getFullName());
            
    switch (student1.getGrade()) {
            
    case A:
                outputText.append(
    " excelled with a grade of A");
                
    break;
            
    case B: // fall through to C
            case C:
                outputText.append(
    " passed with a grade of ")
                .append(student1.getGrade().toString());
                
    break;
            
    case D: // fall through to F
            case F:
                outputText.append(
    " failed with a grade of ")
                .append(student1.getGrade().toString());
                
    break;
            
    case INCOMPLETE:
                outputText.append(
    " did not complete the class.");
                
    break;
            
    default:
                outputText.append(
    " has a grade of ")
                .append(student1.getGrade().toString());
            }

            out.println(outputText.toString());
        }

    Tiger simply requires that you not preface each enumerated type with the enum class name. In fact, it's a compilation error if you do!

    3.5 Maps of Enums

    You'll need to use the java.util.EnumMap class to accomplish this, which is a new collection type just perfect for the job. First, you need to define the enum you want to use for a keyset:

        public enum AntStatus {
            INITIALIZING,
            COMPILING,
            COPYING,
            JARRING,
            ZIPPING,
            DONE,
            ERROR
        }

    You can now create a new EnumMap, and pass the EnumMap the Class object for the enum used for the keyset:

        public void testEnumMap(PrintStream out) throws IOException {
            
    // Create a map with the key and a String message
            EnumMap<AntStatus, String> antMessages = new EnumMap<AntStatus, String>(
                    AntStatus.
    class);
            
    // Initialize the map
            antMessages.put(AntStatus.INITIALIZING, "Initializing Ant");
            antMessages.put(AntStatus.COMPILING, 
    "Compiling Java classes");
            antMessages.put(AntStatus.COPYING, 
    "Copying files");
            antMessages.put(AntStatus.JARRING, 
    "JARring up files");
            antMessages.put(AntStatus.ZIPPING, 
    "ZIPping up files");
            antMessages.put(AntStatus.DONE, 
    "Build complete.");
            antMessages.put(AntStatus.ERROR, 
    "Error occurred.");
            
    // Iterate and print messages
            for (AntStatus status : AntStatus.values()) {
                out.println(
    "For status " + status + ", message is: "
                        
    + antMessages.get(status));
            }

        }

    3.6 Sets of Enums

    Similar to Maps of Enums, but use java.util.EnumSet. Here are the methods of this class you should be concerned with, most of which are factories:

           // Returns a new EnumSet with all elements from the supplied type
           public static EnumSet allOf(Class elementType);

           
    // Returns a new EnumSet of the same type as the supplied set, but
           
    // with all the values not in the supplied set; a mirror image
           public static EnumSet complementOf(EnumSet e);

           
    // Returns a new EnumSet from the provided collection
           public static EnumSet copyOf(Collection c);

           
    // Returns a new EnumSet with no values in it
           public static EnumSet noneOf(Class elementType);

           
    // Various methods to create an EnumSet with the supplied elements in it
           public static EnumSet of(E e[, E e2, E e3, E e4, E e5]);

           
    // Varags version
           public static EnumSet of(E e);

           
    // Creates an EnumSet with a range of values
           public static EnumSet range(E from, E to);

           
    // returns a copy of the current set - not a factory method
           public EnumSet clone( );

    3.7 Adding Methods to an Enum

        public enum GuitarFeatures {
            ROSEWOOD(
    0), // back/sides
            MAHOGANY(0), // back/sides
            ZIRICOTE(300), // back/sides
            SPRUCE(0), // top
            CEDAR(0), // top
            AB_ROSETTE(75), // abalone rosette
            AB_TOP_BORDER(400), // abalone top border
            IL_DIAMONDS(150), // diamond/square inlay
            IL_DOTS(0); // dots inlays

            
    /** The upcharge for the feature */
            
    private float upcharge;

            GuitarFeatures(
    float upcharge) {
                
    this.upcharge = upcharge;
            }


            
    public float getUpcharge() {
                
    return upcharge;
            }

        }


        
    public String getDescription() {
            
    switch (this{
            
    case ROSEWOOD:
                
    return "Rosewood back and sides";
            
    case MAHOGANY:
                
    return "Mahogany back and sides";
            
    case ZIRICOTE:
                
    return "Ziricote back and sides";
            
    case SPRUCE:
                
    return "Sitka Spruce top";
            
    case CEDAR:
                
    return "Wester Red Cedar top";
            
    case AB_ROSETTE:
                
    return "Abalone rosette";
            
    case AB_TOP_BORDER:
                
    return "Abalone top border";
            
    case IL_DIAMONDS:
                
    return "Diamonds and squares fretboard inlay";
            
    case IL_DOTS:
                
    return "Small dots fretboard inlay";
            
    default:
                
    return "Unknown feature";
            }

        }

    There are quite a few things here that you'll need to take note of. First, the class now has a constructor that takes in a float parameter for the upcharge of each feature. As a result, each enumerated type now passes in a parameter to the constructor.

    Then, variables are declared, and methods appear, just like any other class.

    You cannot put your variable declarations before the enumerated values. All declarations must follow the enumerated type declarations.

    ...limiting access to the enum constructor? Enum constructors are implicitly private, so this is taken care of for you.

    3.8 Implemening Interfaces with Enums

    public class Downloader {
        
    public interface Features {
            
    /** Get the upcharge for this feature */
            
    public float getUpcharge();

            
    /** Get the description for this feature */
            
    public String getDescription();
        }

    }


    It's trivial to make GuitarFeatures implement this interface, as the methods are already written:

    public enum GuitarFeatures implements Features {

    3.9 Value-Specific Class Bodies

    // These are the opcodes that our stack machine can execute.
    enum Opcode {
        
    // Push the single operand onto the stack
        PUSH(1{
            
    public void perform(StackMachine machine, int[] operands) {
                machine.push(operands[
    0]);
            }

        }
    // Remember to separate enum values with commas

        
    // Add the top two values on the stack and put the result
        ADD(0{
            
    public void perform(StackMachine machine, int[] operands) {
                machine.push(machine.pop() 
    + machine.pop());
            }

        }
    ,

        
    /* Other opcode values have been omitted for brevity */

        
    // Branch if Equal to Zero
        BEZ(1{
            
    public void perform(StackMachine machine, int[] operands) {
                
    if (machine.pop() == 0)
                    machine.setPC(operands[
    0]);
            }

        }
    // Remember the required semicolon after last enum value

        
    // This is the constructor for the type.
        Opcode(int numOperands) {
            
    this.numOperands = numOperands;
        }


        
    int numOperands; // how many integer operands does it expect?

        
    // Each opcode constant must implement this abstract method in a
        
    // value-specific class body to perform the operation it represents.
        public abstract void perform(StackMachine machine, int[] operands);
    }

    ...just using a more generic method that determines what to do based on a switch statement? Well, that's a better idea, to be honest. Here's the (much cleaner) way to write OpCode:

    // These are the the opcodes that our stack machine can execute.
    abstract static enum Opcode {
        PUSH(
    1),
        ADD(
    0),
        BEZ(
    1); // Remember the required semicolon after last enum value

        
    int numOperands;

        Opcode(
    int numOperands) {
            
    this.numOperands = numOperands;
        }


        
    public void perform(StackMachine machine, int[] operands) {
            
    switch (this{
            
    case PUSH:
                machine.push(operands[
    0]);
                
    break;
            
    case ADD:
                machine.push(machine.pop() 
    + machine.pop());
                
    break;
            
    case BEZ:
                
    if (machine.pop() == 0)
                    machine.setPC(operands[
    0]);
                
    break;
            
    default:
                
    throw new AssertionError();
            }

        }

    }

    3.10 Manually Defining an Enum

    You couldn't menually define your own enum—at least, not in Tiger. While this is very much an accessible class, and is indeed the base class of all enumerated types in Tiger, the compiler won't let you extend it, as following:

    // Attempting to compile this class give you error
    public class ExtendedEnum extends Enum {

    }

    3.11 Extending an Enum

    Here's another one of those pesky, "You don't" labs. Tiger does not allow extension of an enum. For example:

    // Attempting to compile this class give you error
    public enum CollegeGrade extends Grade { DROP_PASSING, DROP_FAILING }

    In theory, this would take the values Grade.A, Grade.B, and so forth, and add to them two new values, CollegeGrade.DROP_PASSING and CollegeGrade.DROP_FAILING. However, you'll get compilation errors if you try this.

    posted on 2005-12-29 23:28 Scott@JAVA 閱讀(476) 評論(0)  編輯  收藏 所屬分類: Java 5.0 Tiger


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲人配人种jizz| 亚洲短视频在线观看| 亚洲日韩av无码| 亚洲男人第一av网站| 亚洲婷婷天堂在线综合| 亚洲午夜成人精品无码色欲| 色婷婷亚洲一区二区三区| 色婷婷综合缴情综免费观看| 免费观看在线禁片| 免费不卡视频一卡二卡| 国产成人高清精品免费软件 | 1000部拍拍拍18免费网站| 国产成人免费爽爽爽视频| 免费A级毛片无码A∨男男| 亚洲AV无码专区国产乱码电影| 亚洲av永久无码嘿嘿嘿| 免费看美女午夜大片| 国产精品免费观看调教网| 最近免费中文字幕4| 亚洲欧洲久久久精品| 久久国产亚洲高清观看| 老子影院午夜伦不卡亚洲| 久久精品一区二区免费看| 在线观看免费成人| 中文字幕人成人乱码亚洲电影| 亚洲国产成人精品久久| 日日躁狠狠躁狠狠爱免费视频| 最近中文字幕国语免费完整| 无码国模国产在线观看免费| 亚洲国产人成网站在线电影动漫| 亚洲精品无码成人| 13小箩利洗澡无码视频网站免费| 成熟女人牲交片免费观看视频| 国产成人A亚洲精V品无码| 亚洲乱码在线观看| 大地资源在线资源免费观看| 麻豆国产人免费人成免费视频| 亚洲AV午夜成人片| 黄色a级片免费看| 无码乱肉视频免费大全合集| 久久亚洲欧洲国产综合|