Enum?(feat.定数)
ていすう
Enumを理解する前に,定数について簡単に論じた.
定数は不変の値です.
int x = 1; //좌항 변수, 우항 상수
1 = 2; // 1은 2가 될 수 없다.
議長なら...?🎃
定数のこのような特性を利用して、以下の論理を書くことができます.
public class ConstantDemo {
public static void main(String[] args) {
/*
* 1. 사과
* 2. 복숭아
* 3. 바나나
*/
int type = 1;
switch(type){
case 1:
System.out.println(57);
break;
case 2:
System.out.println(34);
break;
case 3:
System.out.println(93);
break;
}
}
}
上記の論理では、数字1に対応する果物はいつでも謝罪しなければならない.注釈が失われたり,注釈とコードとの距離が遠くなったりする場合,コードを理解することは困難である.
コメントより良いコードは「コメントがなくても」理解できるコード!
Namespaceラーメン…?🎃
上に名前があればいいのに.変数は定数であってもよい.変数を指定し、最終的に処理すればよい.また、値が変わらない場合は、インスタンス変数ではなくクラス変数(static)として指定することが望ましい.
public class ConstantDemo {
private final static int APPLE = 1;
private final static int PEACH = 2;
private final static int BANANA = 3;
public static void main(String[] args) {
int type = APPLE;
switch(type){
case APPLE:
System.out.println(57+" kcal");
break;
case PEACH:
System.out.println(34+" kcal");
break;
case BANANA:
System.out.println(93+" kcal");
break;
}
}
}
しかし番組の拡大に伴い、企業に対する定数が増加した.public class ConstantDemo {
// fruit
private final static int APPLE = 1;
private final static int PEACH = 2;
private final static int BANANA = 3;
// company
private final static int GOOGLE = 1;
//private final static int APPLE = 2;
private final static int ORACLE = 3;
public static void main(String[] args) {
int type = APPLE;
switch(type){
case APPLE:
System.out.println(57+" kcal");
break;
case PEACH:
System.out.println(34+" kcal");
break;
case BANANA:
System.out.println(93+" kcal");
break;
}
}
}
この場合、果物APPLEと企業APPLEは同じ名称を有する.APPLEの値が2から1になると定数の概念に反するためエラーが発生します.
(error : Duplicate field ConstantDemo.APPLE)
これらの問題を解決するために、接頭辞を付けましょう.
public class ConstantDemo {
// fruit
private final static int FRUIT_APPLE = 1;
private final static int FRUIT_PEACH = 2;
private final static int FRUIT_BANANA = 3;
// company
private final static int COMPANY_GOOGLE = 1;
private final static int COMPANY_APPLE = 2;
private final static int COMPANY_ORACLE = 3;
public static void main(String[] args) {
int type = FRUIT_APPLE;
switch(type){
case FRUIT_APPLE:
System.out.println(57+" kcal");
break;
case FRUIT_PEACH:
System.out.println(34+" kcal");
break;
case FRUIT_BANANA:
System.out.println(93+" kcal");
break;
}
}
}
インターフェイスなら…?🎃
このように変更すると、重複する名前の確率が低下します.この手法をネーミングスペースと呼ぶ.
しかし、水が散らかっています.きれいに交換するために、インタフェースを使ってみましょう.
interface FRUIT{
int APPLE=1, PEACH=2, BANANA=3;
}
interface COMPANY{
int GOOGLE=1, APPLE=2, ORACLE=3;
}
public class ConstantDemo {
public static void main(String[] args) {
int type = FRUIT.APPLE;
switch(type){
case FRUIT.APPLE:
System.out.println(57+" kcal");
break;
case FRUIT.PEACH:
System.out.println(34+" kcal");
break;
case FRUIT.BANANA:
System.out.println(93+" kcal");
break;
}
}
}
インタフェースがこのように使用できるのは、インタフェースで宣言された変数が無条件に共通の静的fianl属性を持つためです.あの…。もういいです。🎃
しかし、タイプとしてCOMPANY GOGLEを使う人がいたらどうなるのでしょうか.下図のように変更します.
int type = COMPANY.GOOGLE;
結果は57 Kcal!グーグルは57 Kcalです.私たちのコードには2つの常配列があります.果物と企業です.
異なるカテゴリの値間では比較できませんが、2つの定数グループのデータ型は同じなので比較できます.コンパイラにこれらのエラーを事前に見つけてもらいたいです.
(異なるデータ型を設定できる場合?)
class Fruit{
public static final Fruit APPLE = new Fruit();
public static final Fruit PEACH = new Fruit();
public static final Fruit BANANA = new Fruit();
}
class Company{
public static final Company GOOGLE = new Company();
public static final Company APPLE = new Company();
public static final Company ORACLE = new Company();
}
public class ConstantDemo {
public static void main(String[] args) {
if(Fruit.APPLE == Company.APPLE){
System.out.println("과일 애플과 회사 애플이 같다.");
}
}
}
FruitクラスとCompanyクラスを作成し、クラス変数をそのクラスのインスタンスとして使用しています.各変数はfinalなので、staticなのでインスタンスを作成する必要はありません.コンパイルエラーが発生します.これが私たちが望んでいることです.異なるカテゴリの定数に対しては比較さえ禁止されている.エラーはコンパイル時に発生するはずです.実行中に発生したエラーは検出しにくい.しかし、上記のコードには2つの問題があります.1つはswitch文が使用できないこと、2つは宣言が複雑すぎることです.
だから…!!!
Enum👍
Enumを列挙型(列挙タイプ)と呼ぶ.列挙型は相互に関連する定数の集合といえる.上記の例では、FruitとCompanyがリストされています.このモードはjava 1.5から文法的にサポートされ、列挙型である.以前のコードをenumに変えましょう.enum Fruit{
APPLE, PEACH, BANANA;
}
enum Company{
GOOGLE, APPLE, ORACLE;
}
public class ConstantDemo {
public static void main(String[] args) {
/*
if(Fruit.APPLE == Company.APPLE){
System.out.println("과일 애플과 회사 애플이 같다.");
}
*/
Fruit type = Fruit.APPLE;
switch(type){
case APPLE:
System.out.println(57+" kcal");
break;
case PEACH:
System.out.println(34+" kcal");
break;
case BANANA:
System.out.println(93+" kcal");
break;
}
}
}
上のコードではenum Fruit{
APPLE, PEACH, BANANA;
}
Enumはclass,interfaceと同等のフォーマットを持つ単位である.しかしenumは実際にはclassです.便宜上、enumのみに使用される構文フォーマットを有するため、区別するためにenumというキーワードが使用される.上のコードは実際には下のコードと同じです.class Fruit{
public static final Fruit APPLE = new Fruit();
public static final Fruit PEACH = new Fruit();
public static final Fruit BANANA = new Fruit();
private Fruit(){}
}
作成者のアクセス制御者はprivateです.これはクラスFruitがインスタンスとして使用できないことを意味します.他の用途に使用することは禁止されています.これについては、後で説明します.Enumは言語が多くの場所で使用されている設計モデルを採用し、文法要素に簡略化していると言える.
次のコードでコンパイルエラーが発生します./*
if(Fruit.APPLE == Company.APPLE){
System.out.println("과일 애플과 회사 애플이 같다.");
}
*/
これはenumがコンパイル時に異なる定数グループの比較を遮断できることを意味する.enumも定数グループでクラスを作成する効果があることがわかります.
enumを使うメリット
enum Fruit{
APPLE, PEACH, BANANA;
}
enum Company{
GOOGLE, APPLE, ORACLE;
}
public class ConstantDemo {
public static void main(String[] args) {
/*
if(Fruit.APPLE == Company.APPLE){
System.out.println("과일 애플과 회사 애플이 같다.");
}
*/
Fruit type = Fruit.APPLE;
switch(type){
case APPLE:
System.out.println(57+" kcal");
break;
case PEACH:
System.out.println(34+" kcal");
break;
case BANANA:
System.out.println(93+" kcal");
break;
}
}
}
enum Fruit{
APPLE, PEACH, BANANA;
}
class Fruit{
public static final Fruit APPLE = new Fruit();
public static final Fruit PEACH = new Fruit();
public static final Fruit BANANA = new Fruit();
private Fruit(){}
}
/*
if(Fruit.APPLE == Company.APPLE){
System.out.println("과일 애플과 회사 애플이 같다.");
}
*/
enum Fruit{
APPLE, PEACH, BANANA;
Fruit(){
System.out.println("Call Constructor "+this);
}
}
enum Company{
GOOGLE, APPLE, ORACLE;
}
public class ConstantDemo {
public static void main(String[] args) {
/*
if(Fruit.APPLE == Company.APPLE){
System.out.println("과일 애플과 회사 애플이 같다.");
}
*/
Fruit type = Fruit.APPLE;
switch(type){
case APPLE:
System.out.println(57+" kcal");
break;
case PEACH:
System.out.println(34+" kcal");
break;
case BANANA:
System.out.println(93+" kcal");
break;
}
}
}
結果は以下の通りです.Call Constructor APPLE
Call Constructor PEACH
Call Constructor BANANA
57 kcal
Call Constructor出力は、ジェネレータFruitが呼び出されたことを意味します.これは3回呼び出され、フィールドの数と同じ数で呼び出されることを意味します.すなわち、enumはジェネレータを有することができる.ただし、コードを次のように変更すると、コンパイルエラーが発生します.
enum Fruit{
APPLE, PEACH, BANANA;
public Fruit(){
System.out.println("Call Constructor "+this);
}
}
これはenumの作成者が制御者privateにのみアクセスできるためです.したがって、直接Fruitを生成することはできません.もしそうであれば、このジェネレータのパラメータ設定フィールド(APPLE...)インスタンス変数の値を指定できますか?あります.しかし、やり方は少し疎い.enum Fruit{
APPLE("red"), PEACH("pink"), BANANA("yellow");
public String color;
Fruit(String color){
System.out.println("Call Constructor "+this);
this.color = color;
}
}
enum Company{
GOOGLE, APPLE, ORACLE;
}
public class ConstantDemo {
public static void main(String[] args) {
/*
if(Fruit.APPLE == Company.APPLE){
System.out.println("과일 애플과 회사 애플이 같다.");
}
*/
Fruit type = Fruit.APPLE;
switch(type){
case APPLE:
System.out.println(57+" kcal, "+Fruit.APPLE.color);
break;
case PEACH:
System.out.println(34+" kcal"+Fruit.PEACH.color);
break;
case BANANA:
System.out.println(93+" kcal"+Fruit.BANANA.color);
break;
}
}
}
実行結果は次のとおりです.Call Constructor APPLE
Call Constructor PEACH
Call Constructor BANANA
57 kcal, red
次のコードはFruitの定数を宣言し、ジェネレータを呼び出します.APPLE("red"), PEACH("pink"), BANANA("yellow");
次のコードはジェネレータです.コンストラクション関数のパラメータとして渡される値はthisです.colorにより、5行のインスタンス変数の値に割り当てられます.Fruit(String color){
System.out.println("Call Constructor "+this);
this.color = color;
}
下図に示すように、呼び出しは、APPLEに割り当てられたFruitインスタンスのcolorフィールドを返します.System.out.println(57+" kcal, "+Fruit.APPLE.color);
列挙型には方法がある可能性があります.次のコードは、前の例と同じ結果を出力します.enum Fruit{
APPLE("red"), PEACH("pink"), BANANA("yellow");
private String color;
Fruit(String color){
System.out.println("Call Constructor "+this);
this.color = color;
}
String getColor(){
return this.color;
}
}
enum Company{
GOOGLE, APPLE, ORACLE;
}
public class ConstantDemo {
public static void main(String[] args) {
Fruit type = Fruit.APPLE;
switch(type){
case APPLE:
System.out.println(57+" kcal, "+Fruit.APPLE.getColor());
break;
case PEACH:
System.out.println(34+" kcal"+Fruit.PEACH.getColor());
break;
case BANANA:
System.out.println(93+" kcal"+Fruit.BANANA.getColor());
break;
}
}
}
Enumは、すべてのメンバーをリストする機能も提供します.enum Fruit{
APPLE("red"), PEACH("pink"), BANANA("yellow");
private String color;
Fruit(String color){
System.out.println("Call Constructor "+this);
this.color = color;
}
String getColor(){
return this.color;
}
}
enum Company{
GOOGLE, APPLE, ORACLE;
}
public class ConstantDemo {
public static void main(String[] args) {
for(Fruit f : Fruit.values()){
System.out.println(f+", "+f.getColor());
}
}
}
リファレンス
https://opentutorials.org/course/1223/6091
Reference
この問題について(Enum?(feat.定数)), 我々は、より多くの情報をここで見つけました https://velog.io/@cms02/Enumテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol