Java枚举深入理解以及HttpStatus类的使用

1枚举

1.1枚举基础

由于每个程序员在开始编程时一般会首先学习C/C++,然后再学习Java,在C++中枚举是可以定义枚举值为特定的整数的,但这在Java中却没有得到支持,大概C/C++中的枚举代表了数值型常量多一些,而Java中枚举值,更确切的说为枚举类型对象。在Java中定义一个简单的枚举类如下所示:

public enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

枚举类与switch-case语句有着天然的结合使用的特性,如对上述的Season类型,编写一个简单的HTTP get接口
代码如下:

     @RequestMapping("/testSeason")
        public String testSeason() {
            Season season = SPRING;
            switch (season) {
                case AUTUMN:
                    System.out.println(season.toString());
                    break;
                case SPRING:
                    System.out.println(season.toString());
                    break;
                case SUMMER:
                    System.out.println(season.toString());
                    break;
                case WINTER:
                    System.out.println("秋天到了");
                    break;
                default:
                    System.out.println("impossible");
                    break;
            }
            return season.toString();//SPRING
        }

1.2高级枚举

在Java中枚举类会默认继承类java.lang.Enum,
在这里插入图片描述
通过IDEA生成Season的继承层次结构图如下:
在这里插入图片描述
关于枚举的常见用法可以参见下图:
在这里插入图片描述

1.2.1 values和 valueOf(String name)

在这里插入图片描述
代码演示上述图片中的前两项

		Season[] seasons = Season.values();
        for (int i = 0; i < seasons.length; i++) {
            System.out.println(seasons[i]);
        }
		/*
			SPRING
			SUMMER
			AUTUMN
			WINTER
		*/
        Season season1 = Season.valueOf("SPRING");
        System.out.println(season1);
        /*
			SPRING
		*/
        System.out.println(season.equals(season1));
        /*
		true
		*/

对应的输出已经打印在显示在代码中,方便理解。
至于高级特性中的多态暂时不在此阐述,编程过程中,不常用。

2 HttpStatus

HttpStatus为建模HTTP的响应码,对于一个HTTP请求,为了表示该次请求在服务器处理时展示的各种情况而建模的,如常见的302表示重定向,而200错误码则表示请求被正确的处理。
之前自己一直不知道该如何为枚举设置特定的值,因为有很多情况比如说出差时开发的访客状态,7表示访客的状态为6、7、8、9,并不是从0开始编写的,当时就写的比较笨,单独去判断是不是等于6,而没有使用HttpStatus类的这种用法。

public enum HttpStatus {
    CONTINUE(100, "Continue"),
    SWITCHING_PROTOCOLS(101, "Switching Protocols"),
    PROCESSING(102, "Processing"),
    CHECKPOINT(103, "Checkpoint"),
    OK(200, "OK"),
    CREATED(201, "Created"),
    ACCEPTED(202, "Accepted"),
    NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information"),
    NO_CONTENT(204, "No Content"),
    RESET_CONTENT(205, "Reset Content"),
    PARTIAL_CONTENT(206, "Partial Content"),
    MULTI_STATUS(207, "Multi-Status"),
    ALREADY_REPORTED(208, "Already Reported"),
    IM_USED(226, "IM Used"),
    MULTIPLE_CHOICES(300, "Multiple Choices"),
    MOVED_PERMANENTLY(301, "Moved Permanently"),
    FOUND(302, "Found"),
    /** @deprecated */
    @Deprecated
    MOVED_TEMPORARILY(302, "Moved Temporarily"),
    SEE_OTHER(303, "See Other"),
    NOT_MODIFIED(304, "Not Modified"),
    /** @deprecated */
    @Deprecated
    USE_PROXY(305, "Use Proxy"),
    TEMPORARY_REDIRECT(307, "Temporary Redirect"),
    PERMANENT_REDIRECT(308, "Permanent Redirect"),
    BAD_REQUEST(400, "Bad Request"),
    UNAUTHORIZED(401, "Unauthorized"),
    PAYMENT_REQUIRED(402, "Payment Required"),
    FORBIDDEN(403, "Forbidden"),
    NOT_FOUND(404, "Not Found"),
    METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
    NOT_ACCEPTABLE(406, "Not Acceptable"),
    PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required"),
    REQUEST_TIMEOUT(408, "Request Timeout"),
    CONFLICT(409, "Conflict"),
    GONE(410, "Gone"),
    LENGTH_REQUIRED(411, "Length Required"),
    PRECONDITION_FAILED(412, "Precondition Failed"),
    PAYLOAD_TOO_LARGE(413, "Payload Too Large"),
    /** @deprecated */
    @Deprecated
    REQUEST_ENTITY_TOO_LARGE(413, "Request Entity Too Large"),
    URI_TOO_LONG(414, "URI Too Long"),
    /** @deprecated */
    @Deprecated
    REQUEST_URI_TOO_LONG(414, "Request-URI Too Long"),
    UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
    REQUESTED_RANGE_NOT_SATISFIABLE(416, "Requested range not satisfiable"),
    EXPECTATION_FAILED(417, "Expectation Failed"),
    I_AM_A_TEAPOT(418, "I'm a teapot"),
    /** @deprecated */
    @Deprecated
    INSUFFICIENT_SPACE_ON_RESOURCE(419, "Insufficient Space On Resource"),
    /** @deprecated */
    @Deprecated
    METHOD_FAILURE(420, "Method Failure"),
    /** @deprecated */
    @Deprecated
    DESTINATION_LOCKED(421, "Destination Locked"),
    UNPROCESSABLE_ENTITY(422, "Unprocessable Entity"),
    LOCKED(423, "Locked"),
    FAILED_DEPENDENCY(424, "Failed Dependency"),
    UPGRADE_REQUIRED(426, "Upgrade Required"),
    PRECONDITION_REQUIRED(428, "Precondition Required"),
    TOO_MANY_REQUESTS(429, "Too Many Requests"),
    REQUEST_HEADER_FIELDS_TOO_LARGE(431, "Request Header Fields Too Large"),
    UNAVAILABLE_FOR_LEGAL_REASONS(451, "Unavailable For Legal Reasons"),
    INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
    NOT_IMPLEMENTED(501, "Not Implemented"),
    BAD_GATEWAY(502, "Bad Gateway"),
    SERVICE_UNAVAILABLE(503, "Service Unavailable"),
    GATEWAY_TIMEOUT(504, "Gateway Timeout"),
    HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version not supported"),
    VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates"),
    INSUFFICIENT_STORAGE(507, "Insufficient Storage"),
    LOOP_DETECTED(508, "Loop Detected"),
    BANDWIDTH_LIMIT_EXCEEDED(509, "Bandwidth Limit Exceeded"),
    NOT_EXTENDED(510, "Not Extended"),
    NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");

    private final int value;
    private final String reasonPhrase;

    private HttpStatus(int value, String reasonPhrase) {
        this.value = value;
        this.reasonPhrase = reasonPhrase;
    }

    public int value() {
        return this.value;
    }

    public String getReasonPhrase() {
        return this.reasonPhrase;
    }

    public boolean is1xxInformational() {
        return HttpStatus.Series.INFORMATIONAL.equals(this.series());
    }

    public boolean is2xxSuccessful() {
        return HttpStatus.Series.SUCCESSFUL.equals(this.series());
    }

    public boolean is3xxRedirection() {
        return HttpStatus.Series.REDIRECTION.equals(this.series());
    }

    public boolean is4xxClientError() {
        return HttpStatus.Series.CLIENT_ERROR.equals(this.series());
    }

    public boolean is5xxServerError() {
        return HttpStatus.Series.SERVER_ERROR.equals(this.series());
    }

    public boolean isError() {
        return this.is4xxClientError() || this.is5xxServerError();
    }

    public HttpStatus.Series series() {
        return HttpStatus.Series.valueOf(this);
    }

    public String toString() {
        return Integer.toString(this.value);
    }

    public static HttpStatus valueOf(int statusCode) {
        HttpStatus status = resolve(statusCode);
        if (status == null) {
            throw new IllegalArgumentException("No matching constant for [" + statusCode + "]");
        } else {
            return status;
        }
    }

    @Nullable
    public static HttpStatus resolve(int statusCode) {
        HttpStatus[] var1 = values();
        int var2 = var1.length;

        for(int var3 = 0; var3 < var2; ++var3) {
            HttpStatus status = var1[var3];
            if (status.value == statusCode) {
                return status;
            }
        }

        return null;
    }
}

该类并不复杂,通过思维导图简单的阐述
在这里插入图片描述
恍然大悟,原来枚举对象也可以有自己的成员,这本身就更加的符合面向对象的思想。而而这些错误码可以继续分类成五种类型,
在这里插入图片描述
在代码中把这些类型构建成了静态内部类,即HttpStatus.Series类。具体源码如下:

public static enum Series {
        INFORMATIONAL(1),
        SUCCESSFUL(2),
        REDIRECTION(3),
        CLIENT_ERROR(4),
        SERVER_ERROR(5);

        private final int value;

        private Series(int value) {
            this.value = value;
        }

        public int value() {
            return this.value;
        }

        public static HttpStatus.Series valueOf(int status) {
            int seriesCode = status / 100;
            HttpStatus.Series[] var2 = values();
            int var3 = var2.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                HttpStatus.Series series = var2[var4];
                if (series.value == seriesCode) {
                    return series;
                }
            }

            throw new IllegalArgumentException("No matching constant for [" + status + "]");
        }

        public static HttpStatus.Series valueOf(HttpStatus status) {
            return valueOf(status.value);
        }
    }

因为Http请求响应码一共有五种,因此一共有5个该类型对象,通过私有化构造器,不允许创建新的系列。并不复杂,不在此赘述了。
关于具体的Http响应码的含义阐述可以参见博客Http错误码从1 到5 详解进行更加准确的理解。

3关于枚举实现接口

关于让枚举类实现接口这个内容,用的很少,暂时贴一下代码,很容易就可以理解,如下的代码通过匿名内部类实现了接口完成了对象的多态展示。代码出处Java 枚举:实现接口

package mark.demo;
 
public class EnumDemo {
 
	public static void main(String[] args) {
		for (Color color : Color.values()) {
			color.setColor();
			color.setType();
		}
	}
 
	interface Paint {
		public void setColor();
 
		public void setType();
	}
 
	public enum Color implements Paint {
		RED("red color", 0) {
			@Override
			public void setColor() {
				System.out.println("Current paint color: " + RED._name);
			}
 
			@Override
			public void setType() {
				System.out.println("Current paint type: " + "5");
			}
		},
		GREEN("green color", 1) {
			@Override
			public void setColor() {
				System.out.println("Current paint color: " + GREEN._name);
			}
 
			@Override
			public void setType() {
				System.out.println("Current paint type: " + "1");
			}
		},
 
		BLUE("blue color", 2) {
			@Override
			public void setColor() {
				System.out.println("Current paint color: " + BLUE._name);
			}
 
			@Override
			public void setType() {
				System.out.println("Current paint type: " + "12");
			}
		},
		YELLOW("yellow color", 3) {
			@Override
			public void setColor() {
				System.out.println("Current paint color: " + YELLOW._name);
			}
 
			@Override
			public void setType() {
				System.out.println("Current paint type: " + "80");
			}
		};
 
		Color(String name, int id) {
			_name = name;
			_id = id;
		}
 
		private String _name;
		private int _id;
 
		public String getName() {
			return _name;
		}
 
		public int getId() {
			return _id;
		}
	}
 
}

3总结

本博客整体思路如下图所示
在这里插入图片描述
对于枚举的使用掌握上述代码中使用的技巧,在很多场景下都足以应对我们的编程问题。HttpStatus类的实现很精彩,读者可以深入研究一下好好理解具体实现的过程。

									2019-03-23 2049于南京大学鼓楼校区207
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值