자료형으로 의미가 부여된 이름을 갖는 상수의 선언
인터페이스 기반의 상수 정의
interface Scale {
int DO = 0;
int RE = 1;
int MI = 2;
int FA = 3;
int SO = 4;
int RA = 5;
int SI = 6;
}
public class Main1 {
public static void main(String[] args) {
int sc = Scale.DO;
switch (sc) {
case Scale.DO:
System.out.println("도");
break;
case Scale.RE:
System.out.println("레");
break;
case Scale.MI:
System.out.println("미");
break;
case Scale.FA:
System.out.println("파");
break;
case Scale.SO:
System.out.println("솔");
break;
case Scale.RA:
System.out.println("라");
break;
default:
System.out.println("시");
}
}
}
인터페이스 내에 선언된 변수는 public, static, final 선언된 것으로 간주. Interface 정의를 통해서 총 7개 상수 선언.
Scale은 음계를 표현한 상수들을 담고 있음. 즉, 상수값 변경되어도 이름이 변경되지 않으면 코드에 아무런 영향이 없다.
interface Animal {
int Dog = 1;
int Cat = 2;
}
interface Person {
int Man = 1;
int Woman = 2;
}
public class Main2 {
public static void main(String[] args) {
who(Person.Man);
}
public static void who(int man) {
switch (man) {
case Person.Man:
System.out.println("남성");
break;
case Person.Woman:
System.out.println("여성");
break;
}
}
}
who(Animal.DOG); // 비정상적 메소드 -> Person.Man도 1, AnimalDog도 값이 1이기에 위와 같은 실수를 범해도 컴피일 오류 X
자료형 부여를 돕는 열거형
enum Scale1{
DO, RE, MI, FA, SO, RA ,TI
}
열거형을 Enum. 열거형은 클래스와 성격이 유사. & 참조변수도 선언도 가능. 선언된 참조변수는 해당 열거형 내에 선언된 열거형 값만 대입이 가능
Scale1 sc = Scale1.DO;
switch (sc){
case DO:
System.out.println("도");
break;
case RE:
System.out.println("레");
break;
case MI:
System.out.println("미");
break;
default:
System.out.println("파라시도");
}
Switch 문으로 형성 가능
enum Animal1{
Dog, Cat
}
enum Person1{
Man, Woman
}
public class Main4 {
public static void main(String[] args) {
who(Person1.Man);
//who(Animal1.Dog);
}
public static void who(Person1 p){
switch (p){
case Man:
System.out.println("남성");
break;
case Woman:
System.out.println("여성");
break;
}
}
}
비정상적 메소드 호출
//who(Animal1.Dog);
Person형 값을 전달하는 상황에서 Animal 형 값이 전달되어 컴파일 오류를 발생.
클래스 내에 정의가 가능한 열거형 정의
class Customer {
enum Gender {
MALE, FEMALE
}
클래스 내에 열거형을 정의 할 수 있다.
특정 클래스 내에서만 사용하고자 하는 열거형 값이 있다면, 해당 클래스 내에 열거형을 정의하면 된다.
class Customer {
enum Gender {
MALE, FEMALE
}
private String name;
private Gender gen;
Customer(String n, String g) {
this.name = n;
if (g.equals("man")){
gen = Gender.MALE;
} else {
gen = Gender.FEMALE;
}
}
@Override
public String toString(){
if (gen == Gender.MALE){
return "Thank u Mr" + name;
} else {
return "Thank u Miss" + name;
}
}
}
public class Main5 {
public static void main(String[] args) {
Customer c1 = new Customer("Brown" , "man");
Customer c2 = new Customer("Cirss" , "Female");
System.out.println(c1);
System.out.println(c2);
}
}
열거형 값의 정체
class Person2{
public static final Person2 Man = new Person2();
public static final Person2 Female = new Person2();
@Override
public String toString(){
return "I'm Dog lover";
}
}
public class Main6 {
public static void main(String[] args) {
System.out.println(Person2.Man);
System.out.println(Person2.Female);
}
}
Person 클래스 내에서 Person형 참조변수를 선언하는 것도, Person 인스턴스를 생성하는 것도 가능. 특정 자료구조를 직접 정의해야 하는 경우에는 이러한 특성을 활용
enum Person4 {
Man, Woman;
@Override
public String toString(){
return "I'm a dog Lover";
}
}
public class Main7 {
public static void main(String[] args) {
System.out.println(Person2.Female);
System.out.println(Person2.Man);
}
}
이 예제는 열거형 값이 해당 자료형의 인스턴스
System.out.println(Person2.Female);
System.out.println(Person2.Man);
toString 메소드 반환 값 출력
모든 열거형은 Enum 클래스를 상속. 그리고 Enum은 Object 클래스를 상속. 두 열거형 값은, Person 인스턴스를 참조하는 참조변수.
열거형 정의에도 생성자가 없으면 디폴트 생성자가 삽입. 다만 이 생성자는 private로 선언되어 직접 인스턴스 생성 제한.
enum People{
Man, Woman;
private People(){
System.out.println("People constructor called");
}
@Override
public String toString(){
return "I Love Dog";
}
}
public class Main8 {
public static void main(String[] args) {
System.out.println(People.Man);
System.out.println(People.Woman);
}
}
생성자가 private이라 실제 컴파일은 안됨.
인자를 전달받는 열거형의 생성자 정의 방법과 이를 호출하는 방법
enum People1{
Man(25), Woman(30);
int age;
private People1(int age){
this.age = age;
}
@Override
public String toString(){
return "My Age" + age;
}
}
public class Main9 {
}
private People1(int age){
this.age = age;
}
열거형 생성자는 무조건 private
모든 생성자를 private으로 선언
매개변수의 가변 인자 선언
Public static int hash(Object … values)
매개변수의 가변 인자 선언과 호출
public class Main10 {
public static void showAll(String...vargs){
System.out.println("LEN: " + vargs.length);
for (String s:
vargs) {
System.out.println(s);
System.out.println();
}
}
public static void main(String[] args) {
showAll("Box");
showAll("Box","Toy");
showAll("Money", "Box", "Apple");
}
}
매개변수를 선언할 때 가변 인자를 선언하면, 전달 되는 인자 수에 제한을 두지 않을 수 있다.
가변인자 선언
public static void showAll(String...vargs){
System.out.println("LEN: " + vargs.length);
vargs가 배열을 참조한다는 뜻. Length에 접근하여 그 길이를 확인 가능.
가변인자 선언에 대한 컴파일 처리
public class Main11 {
public static void showAll(String[] vargs){
System.out.println("LEN :" + vargs.length);
for (String s:
vargs) {
System.out.println(s);
}
}
public static void main(String[] args) {
showAll(new String[]{"Box"});
showAll(new String[]{"Box", "Toy"});
showAll(new String[]{"Box", "Toy", "Doll"});
}
}
가변인자 선언을 기반으로 작성된 메소드 정의와 호출문
public static void showAll(String[] vargs){
System.out.println("LEN :" + vargs.length);
public static void main(String[] args) {
showAll(new String[]{"Box"});
showAll(new String[]{"Box", "Toy"});
showAll(new String[]{"Box", "Toy", "Doll"});
}
}
또는
Public static void showAll(String[] vargs) {}
Public static void main(String[] args){
showAll(new String[]{Box});
자바 컴파일러가 가변 인자 및 메소드 호출문을 처리하는 방식
어노테이션
어노테이션은 자바 컴파일러에게 메시지를 전달하는 목적의 메모.
어노테이션의 설명 범위
@Override
@Deprecated
@SuppressWarnings
@Override
@Deprecated
public void showIt(String str);
public void brshowId(String str);
}
class Viewer implements Viewable{
@Override
public void showIt(String str) {
System.out.println(str);
}
@Override
public void brshowId(String str) {
System.out.println(str);
}
}
public class Main12 {
@SuppressWarnings("decrecation")
public static void main(String[] args) {
Viewable viewable = new Viewer();
viewable.showIt("Hello Annotation");
viewable.brshowId("Hello Annotation");
}
}
상속 Override 뿐만 아니라 인터페이스 구현을 위한 메소드 오버라이드도 가능
즉, 상위 클래스의 메소드 오버라이딩 또는 인터페이스에 선언된 추상 메소드 구현
@Deprecated
문제의 발생이 있거나, 개선된 기능의 다른 것으로 대체되어서 더 이상 필요 없음
아직은 호환성 유지를 위해 존재, 이후에 사라질 수 있는 클래스 또는 메소드는 가리켜 Deprecated 되었다고 한다
@Deprecated
public void showIt(String str);
컴파일은 잘 된다. 단 메시지를 하나 던져준다.
컴파일된 코드에 deprecated된 무언가를 사용했음을 알리는 메시지.
구체적으로 어느부분이 이런 일 발생 했는지 알고 싶다면, 옵션 추가.
@SupressWarnings
해당 메소드를 대체할 수 있는 상황이 아니라서 당분간 그 메소드를 구현하고 호출하는 상황이라면 위 메소드 호출, 그리고 컴파일 경고 지움
public class Main12 {
@SuppressWarnings("decrecation")
public static void main(String[] args) {
Viewable viewable = new Viewer();
viewable.showIt("Hello Annotation");
viewable.brshowId("Hello Annotation");
}
}
경고 대상에서 제외
public class Main13 {
@SuppressWarnings({"fallingthrough", "decription"})
public static void main(String[] args) {
int n = 3;
switch (n){
case 1:
System.out.println(n);
case 2:
System.out.println(n);
case 3:
System.out.println(n);
}
}
}
위 예제의 경우 break 없음. 컴파일은 이부분을 경고.
@SuppressWarnings({"fallingthrough", "decription"})
이부분 추가하면 경고 사라진다.