Java Enum 및 Switch 문-기본 케이스?
예외 던지기를 제안하는 사람들의 경우 : 예외를
던진다 고해서 컴파일 타임 오류가 발생하지 않고 런타임 오류가 발생합니다. 나는 예외를 던질 수 있다는 것을 알고 있으며, 런타임보다는 컴파일 중에 죽는 것이 더 낫다.
우선, 나는 이클립스 3.4를 사용하고 있습니다.
Enum 인 mode 속성이있는 데이터 모델이 있습니다.
enum Mode {on(...), off(...), standby(...); ...}
현재이 모델의보기를 작성 중이며 코드가 있습니다.
...
switch(model.getMode()) {
case on:
return getOnColor();
case off:
return getOffColor();
case standby:
return getStandbyColor();
}
...
"이 메서드는 java.awt.Color 형식의 결과를 반환해야합니다."라는 오류가 발생합니다. 기본 대 / 소문자가없고 함수 끝에 xxx를 반환하지 않기 때문입니다. 내가 원하는 내가 지정해 AssertionError를 throw 기본 케이스를 넣어하지 않도록이 수정 모드로 컴파일하고로 볼 수없는 것처럼 누군가가 열거에 (예를 들어 shuttingdown를) 다른 유형을 추가하는 경우 경우 컴파일 오류 런타임까지 오류.
내 질문은 다음과 같습니다.
EclipseBuilder (및 javac)가이 스위치가 모든 가능성을 처리한다는 것을 인식하지 못하는 이유는 무엇입니까 (또는 해당 기능을 포함합니까?). 반환 유형이 필요하다는 경고를 중지합니다. 모드에 메소드를 추가하지 않고 내가 원하는 것을 할 수있는 방법이 있습니까?
실패하면 Enum의 가능한 값을 모두 다루지 않는 switch 문에 대해 경고 / 오류 옵션이 있습니까?
편집 : Rob : 컴파일 오류 입니다. 방금 javac로 컴파일을 시도했는데 메소드의 마지막}을 대상으로하는 "missing return statement"오류가 발생합니다. Eclispe는 메서드의 맨 위에 오류를 표시합니다.
Enum with Visitor 패턴을 항상 사용할 수 있습니다.
enum Mode {
on {
public <E> E accept( ModeVisitor<E> visitor ) {
return visitor.visitOn();
}
},
off {
public <E> E accept( ModeVisitor<E> visitor ) {
return visitor.visitOff();
}
},
standby {
public <E> E accept( ModeVisitor<E> visitor ) {
return visitor.visitStandby();
}
}
public abstract <E> E accept( ModeVisitor<E> visitor );
public interface ModeVisitor<E> {
E visitOn();
E visitOff();
E visitStandby();
}
}
그런 다음 다음과 같은 것을 구현합니다.
public final class ModeColorVisitor implements ModeVisitor<Color> {
public Color visitOn() {
return getOnColor();
}
public Color visitOff() {
return getOffColor();
}
public Color visitStandby() {
return getStandbyColor();
}
}
다음과 같이 사용합니다.
return model.getMode().accept( new ModeColorVisitor() );
이것은 훨씬 더 장황하지만 새로운 enum이 선언되면 즉시 컴파일 오류가 발생합니다.
Eclipse (창-> 환경 설정)에서 "Enum type constant not covered in switch"설정을 오류 수준으로 활성화해야합니다.
메소드 끝에 예외를 던지지 만 기본 케이스를 사용하지 마십시오.
public String method(Foo foo)
switch(foo) {
case x: return "x";
case y: return "y";
}
throw new IllegalArgumentException();
}
이제 누군가가 나중에 새 케이스를 추가하면 Eclipse는 케이스가 누락되었음을 알립니다. 그러니 정말 타당한 이유가 없다면 기본값을 사용하지 마십시오.
이 오류가 발생하는 이유를 모르겠지만 여기에 제안이 있습니다. 열거 형 자체에서 색상을 정의하지 않는 이유는 무엇입니까? 그러면 실수로 새 색상을 정의하는 것을 잊을 수 없습니다.
예를 들면 :
import java.awt.Color;
public class Test {
enum Mode
{
on (Color.BLACK),
off (Color.RED),
standby (Color.GREEN);
private final Color color;
Mode (Color aColor) { color = aColor; }
Color getColor() { return color; }
}
class Model
{
private Mode mode;
public Mode getMode () { return mode; }
}
private Model model;
public Color getColor()
{
return model.getMode().getColor();
}
}
btw, 비교를 위해 컴파일러 오류가있는 원래의 경우입니다.
import java.awt.Color;
public class Test {
enum Mode {on, off, standby;}
class Model
{
private Mode mode;
public Mode getMode () { return mode; }
}
private Model model;
public Color getColor()
{
switch(model.getMode()) {
case on:
return Color.BLACK;
case off:
return Color.RED;
case standby:
return Color.GREEN;
}
}
}
model.GetMode () 가 null을 반환 할 수 있기 때문일 것입니다 .
예외를 발생시키는 기본 케이스를 작성하십시오.
throw new RuntimeExeption("this code should never be hit unless someone updated the enum")
... 그리고 그것은 Eclipse가 불평하는 이유를 거의 설명합니다. 스위치가 오늘 모든 열거 형 케이스를 커버 할 수 있지만 누군가가 케이스를 추가하고 내일 다시 컴파일하지 않을 수 있습니다.
Why does EclipseBuilder not recognize that this switch covers all possibilities (or does it cover them?) and stop warning me about needing a return type. Is there a way I can do what I want without adding methods to Mode?
It's not an issue in Eclipse, but rather the compiler, javac
. All javac
sees is that you don't have a return value in the case in which nothing is matched (the fact that you know you are matching all cases is irrelevant). You have to return something in the default case (or throw an exception).
Personally, I'd just throw some sort of exception.
Your problem is that you are trying to use the switch statement as an indicator that your enum is locked down.
The fact is that the 'switch' statement and the java compiler cannot recognize that you do not want to allow other options in your enum. The fact that you only want three options in your enum is completely separate from your design of the switch statement, which as noted by others should ALWAYS have a default statement. (In your case it should throw an exception, because it is an unhandled scenario.)
You should liberally sprinkle your enum with comments so that everyone knows not to touch it, and you should fix your switch statement to throw errors for unrecognized cases. That way you've covered all the bases.
EDIT
On the matter of throwing compiler error. That does not strictly make sense. You have an enum with three options, and a switch with three options. You want it to throw a compiler error if someone adds a value to the enum. Except that enums can be of any size, so it doesn't make sense to throw a compiler error if someone changes it. Furthermore, you are defining the size of your enum based on a switch statement which could be located in a completely different class.
The internal workings of Enum and Switch are completely separate and should remain uncoupled.
A nice way for this would be to add the default case to return some error value or throw exception and to use automated tests with jUnit, for example:
@Test
public void testEnum() {
for(Mode m : Mode.values() {
m.foobar(); // The switch is separated to a method
// If you want to check the return value, do it (or if there's an exception in the
// default part, that's enough)
}
}
When you got automated tests, this will take care of that foobar is defined for all enumerations.
Since I can't just comment...
Always, Always, Always have a default case. You'd be surprised how "frequently" it would be hit (Less in Java than C, but still).
Having said that, what if I only want to handle only on/off in my case. Your semantic processing by javac would flag that as an issue.
Nowadays (this answer is written several years after the original question), eclipse allows following configuration at Window -> Preferences -> Java -> Compiler -> Error/warnings -> Potential programming problems:
Incomplete switch cases
Signal even if default case exists
ReferenceURL : https://stackoverflow.com/questions/859563/java-enums-and-switch-statements-the-default-case
'IT story' 카테고리의 다른 글
패턴과 일치하는 키 수 (0) | 2020.12.28 |
---|---|
express.json 대 bodyParser.json (0) | 2020.12.28 |
텍스트의 URL을 HTML 링크로 교체 (0) | 2020.12.28 |
jquery.validate 플러그인-양식 유효성 검사 전에 값을 자르는 방법 (0) | 2020.12.28 |
자바에서 문자 자르기 (0) | 2020.12.28 |