총 게시물 25건, 최근 0 건 안내 RSS 글쓰기
이전글  다음글  목록 글쓰기
[1.기본 지식편]

3장 클래스 구성

글쓴이 : 카이로 날짜 : 2014-01-22 (수) 08:46 조회 : 9933
글주소 : http://www.androidside.com/430/34
 
  모두가 행복한 프리베뉴
개인모임부터 전문세미나까지 모든 모임공고 및 접수, 장소 예약 대행 서비스
pre-venue.com
  코딩교육전문기관 박인수
C언어,자료구조,C++,파이썬 코딩전문교육, 코딩역량테스트 대비, 저학년코딩교육
kgitbankedu.co.kr
  인터넷게임추천사이트 예스파일
최신영화, TV방송, 애니 무료다운, 웹툰, 웹소설 모바일 100%지원 인터넷게임
www.yesfile.co
신청하기


3장  클래스 구성
3.1  소개
클래스는 자바 프로그래밍에서 가장 핵심적인 요소로서 프로그램을 실행하기 위한 최소 단위이다. 그렇기 때문에 클래스를 얼마나 잘 설계하느냐가 전체 프로그램의 완성도를 결정하는 관건이 된다. 자바 프로그래밍에서는 클래스를 작성하는 기본적인 규칙이 있다. 이 규칙을 이 장에서 살펴보도록 하겠다.

그림 3-1-1 클래스 구성도
 
3-1-1.png

자바 클래스는 일반적으로 멤버 변수(Member Variable), 생성자(Constructor), 메소드(Method)로 구성되며 상황에 따라 이 구성 요소들 중 필요 없는 부분은 생략할 수 있다. 그렇기 때문에 멤버 변수만 선언하거나 모든 구성 요소를 선언하지 않는 것이 가능하다. 클래스의 구성 요소 중 멤버 변수에는 static 제한자 선언 여부에 따라 구분되는 클래스 변수(Class Variable)와 인스턴스 변수(Instance Variable)를 선언할 수 있으며 메소드에는 매개 변수(Parameter)와 자동 변수(Automatic Variable)를 선언할 수 있다. 이들 구성 요소에 대한 자세한 설명은 차후에 다시 살펴보기로 하고 여기서는 클래스의 구성 요소를 보여주는 전체 소스 코드를 살펴보는 것으로 클래스에 대한 기본적인 설명을 마칠까 한다. 

코드)
public
class Account {
    // 클래스 변수
    static int account_no;

    //인스턴스 변수
    private String name;
    private String jumin_id;

   
    public Account() {
        account_no++;
    }

    
    public Account(String name, String jumin_id) {
        account_no++;
        this.name = name;
        this. jumin_id = jumin_id;
    }   

    

    public voidsetJumin_id(String jumin_id) {
        this. jumin_id = jumin_id;
    }
}


3.2  키워드(Keyword)
키워드는 자바에서 특정 용도로 사용하기 위해 미리 예약되어 있는 단어이기 때문에 변수명, 메소드명, 클래스명으로 선언하여 사용할 수 없다. 다음 표와 같이 키워드를 알파벳 순으로 나열해 보면 JAVA 5.0 에 추가된 키워드를 포함해서 총 50가지의 키워드가 예약되어 있는 것을 알 수 있다. 추가적으로 다음 표에 등록되어 있지 않은 true, false, null 은 자바의 키워드는 아니지만 예약어로 등록되어 있기 때문에 프로그램에서 변수명이나 메소드명, 클래스명으로 사용할 수 없다는 것에 주의해야 한다.

3-1-1 키워드 종류
3-2-1.PNG
※ const, goto 는 사용되지 않는 키워드이다.
※ strictfp 는 JAVA 1.2 에서 추가된 키워드이다.
※ assert 는 JAVA 1.4 에서 추가된 키워드이다.
※ enum 은 JAVA 5.0(1.5)에서 추가된 키워드이다.

참고로 Byte, Short, Character, Integer, Long, Float, Double은 기본 데이터형에 사용하는 키워드와 이름이 유사하기는 하지만 키워드는 아니다. 이것은 래퍼 클래스(Wrapper Class)로서 기본 데이터형과 관련된 여러 기능들을 묶어 놓은 클래스일 뿐이다.



3.3  식별자(Identifier)
식별자(Identifier)는 클래스, 인터페이스, 메소드, 변수, 문자열, 배열 등을 구분하는 이름을 말한다. 식별자는 개발자 임의로 정의하여 사용할 수 있지만 적어도 아래의 규칙은 지켜서 이름을 작성해야 한다.

정리 식별자 선언 규칙
1. 식별자의 첫 문자에는 숫자가 올 수 없다.
2. 식별자는 알파벳 대문자, 소문자, 숫자, _(밑줄 문자), $(달러 문자)로만 구성해야 한다.
3. 키워드를 식별자로 사용할 수 없다.
4. 공백은 사용할 수 없다.

식별자는 선언 규칙에 따른 특징 이외의 자바 언어의 고유 특징으로 인해 다음과 같은 특징을 추가적으로 가진다.

정리 식별자의 추가 특징
1. 길이 제한이 없다.
2. 대소문자를 구분한다.
3. 유니코드 문자로 선언할 수 있다.


이제 유효한 식별자와 그렇지 못한 식별자를 살펴보도록 하자. 

유효한 식별자(Valid Identifier)
MyProg, Integer, my_prog, $prog, Int,
string, my__prog, _1234

잘못된 식별자(Invalid Identifier)
2test, interface, class, int, char, public, null

Integer는 래퍼 클래스(Wrapper Class)일 뿐 키워드는 아니기 때문에 프로그램에서 사용할 수 있으며 Int도 기본 데이터형인 int와는 다른 단어이기 때문에 식별자로 사용할 수 있다. 그리고 _1234는 식별자 선언 규칙을 지켜 작성된 단어이기 때문에 이상 없이 사용할 수 있다. 하지만 interface나 class와 같은 단어는 키워드이기 때문에 식별자로 사용할 수 없다. 식별자의 첫 문자는 숫자가 올 수 없기 때문에 2test는 식별자가 될 수 없다.

식별자 선언 규칙은 변수나 메소드명을 선언하는 데 있어서 최소한의 규칙이기 때문에 개발자가 원하는 방식으로 변수와 메소드명을 선언하면 가독성이 떨어질 수 있다. 그래서 대부분의 자바 개발자들은 가독성을 높이기 위해 아래와 같은 명명 규칙을 지켜 코드를 작성한다.

정리 식별자 명명 규칙
1. 변수나 메소드의 첫 문자는 소문자로 한다.
2. 클래스나 인터페이스의 첫 문자는 대문자로 한다.
3. 변수와 클래스 이름은 명사로 작성하며 메소드의 이름은 동사로 작성한다.
4. 단어 결합시에는 결합되는 단어를 대문자로 시작하거나 _(밑줄 문자)를 이용하여 단어를 결합한다.
5. 식별자 선언시 되도록 대문자, 소문자, _(밑줄 문자)만을 이용한다.


3.4  데이터형(Data Types)
자바에서 사용할 수 있는 데이터형에는 기본 데이터형(Primitive Data Type)과 참조형(Reference Type)이 있다. 먼저 기본 데이터형은 선언된 변수에 값을 바로 할당하는 int, long, double 형 등을 말하며 참조형은 생성된 객체의 주소만을 변수에 할당하는 데이터형을 말한다. 참조형에는 배열, 클래스, 인터페이스 등이 있다. 이러한 데이터형을 정리하면 다음과 같다.

그림 3-4-1 데이터형 분류
 3-4-1.png


3.4.1  기본 데이터형(Primitive Data Type)
기본 데이터형은 크게 정수형, 실수형, 문자형, 논리형으로 구분할 수 있다. 정수형에는 byte, short, int, long 형이 있으며 실수형에는 float, double 형이 있다. 그리고 문자형에는 char 형이 있으며 논리형에는 boolean 형이 있다. 이러한 자바의 기본 데이터형을 표로 정리하면 다음과 같다.

표 3-2-1-1 기본 데이터형
3-4-1-1.PNG

기본 데이터형은 저장할 수 있는 데이터 범위가 정해져 있기 때문에 데이터 범위를 초과하는 데이터를 저장할 수 없다. 예를 들어서 4Byte 크기를 가지는 int 형에 8Byte 크기를 가지는 데이터를 저장할 수 없다. 그래도 어떻게든 저장하고 싶다면 4Byte 를 버리고 남는 4Byte 만을 저장해야 한다. 이렇게 하기 위해서는 기본 데이터형을 형변환해야 한다. 형변환은 특정 데이터형을 다른 데이터형으로 변환하기 위한 것으로 캐스팅(Casting)과 컨버젼(Conversion)으로 구분할 수 있다. 먼저 캐스팅은 참조형을 변환하는 것을 말하며 컨버젼은 기본 데이터형을 변환하는 것을 말한다. 이에 대해서는 뒤에서 더 자세히 다루도록 하겠다.


이제 이러한 기본 데이터형으로 선언한 변수에 어떻게 값을 저장할 수 있는지를 살펴보도록 하자.

표 3-2-1-2 기본 데이터형 사용 예제
3-4-1-2.PNG

이 표를 통해서 알 수 있는 사실은 숫자 뒤에 숫자의 데이터형을 지정하기 위한 특정 문자를 붙일 수도 있다는 것이다. 예를 들어 long 형에는 대문자(L), 소문자(l)를 붙일 수 있으며 float 형에는 대문자(F), 소문자(f) 를 붙일 수 있다. 마찬가지로 double 형에는 대문자(D), 소문자(d) 를 붙일 수 있다. 만약 이러한 특정 문자를 붙이지 않았을 경우에는 해당 숫자는 자동적으로 데이터형 구분에 맞는 대표 데이터형으로 인식된다. 정수형의 대표 데이터형은 int 형이며 실수형의 대표 데이터형은 double 형이다.


3.4.2  참조형(Reference Type)
참조형은 자바에서 생성된 객체의 주소를 가지고 있는 데이터형을 말한다. 기본 데이터형은 숫자나 문자, 논리값을 직접적으로 가지고 있는 반면에 참조형은 생성된 객체를 직접적으로 가지고 있는 것이 아니라 생성된 객체의 주소만을 가지고 있다. 이와 같은 참조형에는 배열, 클래스, 인터페이스가 있다. 이들을 사용하기 위해서는 먼저 객체를 생성하고 생성한 객체의 주소를 가지고 있는 변수를 이용해서 객체에 접근해야 한다.

참조형의 사용 예제를 보면 다음과 같다.

표 3-2-2-1 참조형 사용 예제
3-4-2-1.PNG
※ 기본 데이터형 이외에는 모두 참조형이다.


3.4.3  배열(Array)
배열은 동일한 형의 데이터를 여러 개 담을 수 있는 구조로서 자바에서는 참조형으로 처리된다. 배열에 대한 이해를 돕기 위해 배열 구조를 설명하는 간단한 그림을 먼저 살펴보도록 하겠다.

다음은 int 형 데이터를 저장하기 위한 1차원 배열 구조를 보여준다. 먼저 int 형 배열을 생성하기 위해 int[] arr = new int[5] 를 선언하다. 여기서 int[5] 는 int 형 데이터를 5개 담을 수 있는 공간을 만들어 놓으라는 얘기이다. 이렇게 선언된 이후에는 배열의 길이는 변경될 수 없다. 그 다음 arr[0] = 5 와 같이 선언하여 생성된 배열 공간에 값을 할당한다. 여기서 배열의 첫 번째 공간은 0번 인덱스로 참조되며 마지막 공간의 인덱스는 (선언된 크기 ? 1)이 된다. 그래서 이 배열의 마지막 공간은 (5 ? 1)이 되어 인덱스 4가 된다. 

그림 3-4-3-1 배열 구조
 
3-4-3-1.PNG

배열은 선언에 따라 1차원 배열이 될 수도 있고 2차원 배열이 될 수도 있다. 물론 3차원 배열이 될 수도 있다. 하지만 3차원 배열은 사용하기가 복잡하여 자주 사용하지 않는다. 

배열은 다양한 방법으로 선언해서 사용할 수 있다. 다음 그림들은 1차원 배열과, 2차원 배열을 선언하는 방법을 보여준다. 그리고 선언 방법 옆의 표는 해당 코드에 의해 생성된 배열의 인덱스와 데이터를 나타낸다.


그림 3-4-3-2 1차원 배열
 
3-4-3-2.PNG


지금까지 배열의 구조와 배열을 선언하는 방법에 대해서 살펴보았다. 배열을 선언하는 방법은 변수를 선언하는 방법과는 다르지만 그 방법이 어렵지는 않다는 것을 알 수 있을 것이다. 이제 배열이 가진 특징에 대해서 정리하도록 하자.

배열(Array)의 특징
1. 객체와 배열을 포함한 어떤 데이터형도 저장할 수 있다.
2. 고정 길이를 가지기 때문에 선언된 길이를 수정할 수 없다.
3. 배열의 길이는 배열 속성 변수 length로 알 수 있다.
4. 배열의 데이터는 인덱스로 접근할 수 있다.
5. 배열의 시작 인덱스는 0이며 마지막 인덱스는 배열 길이 - 1이다.
6. 배열은 서로 다른 데이터형을 저장할 수 없다.

배열은 항상 선언된 길이로만 사용할 수 있기 때문에 데이터를 얼마나 저장해야 할 지 모르는 경우에는 배열은 적당하지 않은 방법이다. 이러한 경우에는 이후에 살펴볼 컬렉션 클래스를 사용하는 것이 좋다. 컬렉션 클래스는 개발자가 길이를 지정하지 않아도 자동적으로 길이를 증가시켜 데이터를 계속해서 저장할 수 있도록 설계되어 있기 때문에 배열보다 사용하기가 편한다. 

[TIP&TECH] 
컬렉션 클래스는 java.util 패키지에 있는 Collection 인터페이스를 상속하는 Set, List 인터페이스의 구현 클래스와 Map 인터페이스를 구현하는 클래스들을 말한다. 이에 대한 자세한 내용은 이 책의 컬렉션 부분을 살펴보기를 바란다.

마지막으로 배열을 사용하는 완전한 코드를 보도록 하자.

public class Test {
    public static void main(String[] args) {
        int[] arr = new int[5];
       
        arr[0] = 5;
        arr[1] = 4;
        arr[2] = 3;
        arr[3] = 2;
        arr[4] = 1;

        System.
out.println("array size : " + arr.length);
        System.out.println("arr[3] value : " + arr[3]);
    }
}



3.5  변수(Variable)
변수는 데이터를 저장하기 위한 공간이다. 이 공간에는 기본 데이터형과 참조형 모두 저장될 수 있다. 기본 데이터형이 저장되면 해당 데이터가 그대로 저장되며 참조형이 저장될 경우에는 객체의 주소가 저장된다. 

변수는 접근 범위에 따라 멤버 변수와 자동 변수로 분류할 수 있으며 멤버 변수는 다시 클래스 변수와 인스턴스 변수로 분류할 수 있다.

그림 3-3-1 변수의 종류
 
3-5-1.PNG


3.5.1  멤버 변수와 자동 변수
변수는 선언되는 위치에 따라 멤버 변수와 자동 변수로 분류된다. 멤버 변수(Member Variable)는 메소드와 동등한 레벨에 선언된 변수를 말하며 자동 변수(Automatic Variable)는 메소드와 같은 블록 내에 선언된 변수를 말한다. 자동 변수는 지역 변수(Local Variable) 라 하기도 한다.

멤버 변수와 자동 변수를 소스 코드로 살펴보면 다음과 같다.

1) 멤버 변수
멤버 변수는 메소드와 같이 메소드 레벨에 선언되기 때문에 메소드에서 해당 변수를 참조할 수 있다. 그래서 m1() 메소드에서는 변수 a 와 b 에 접근할 수 있다.

class
MemberTest {
    int a;
    staticString b;
   
    public voidm1() {
        //....
    }
}
 

2) 자동 변수
자동 변수는 멤버 변수처럼 메소드 레벨이 아닌 메소드와 같은 블록 내에 선언되는 변수를 말한다. 다음의 예제 코드에서 m1() 메소드의 a 와 b 그리고 m2() 메소드의 c 와 d 가 자동 변수가 된다. 자동 변수는 해당 블록 내에서만 접근이 가능하기 때문에 m1() 메소드에서 m2 메소드의 변수에 접근할 수 없으며 반대의 경우도 마찬가지이다. 또한 m2() 메소드의 매개 변수(Parameter)인 int 형 변수 e 는 메소드 내에 선언되는 자동 변수와 비슷한 접근 범위를 가지기 때문에 이 메소드의 외부에서는 이 변수에 접근할 수 없다.

class AutoTest {
    public voidm1() {
        int a;
        String b;
    }

    
public voidm2(int e) {
        int c;
        String d;
    }
}


3.5.2  클래스 변수와 인스턴스 변수
메소드 레벨에 선언되는 멤버 변수는 static 제한자의 선언 여부에 따라서 클래스 변수와 인스턴스 변수로 분류된다. 클래스 변수(Class Variable)는 static 제한자가 선언된 변수를 말하며 인스턴스 변수(Instance Variable)는 static 제한자가 선언되지 않은 변수를 말한다.

클래스 변수는 클래스가 로딩되면서 메모리에 설정되는 변수이기 때문에 객체의 참조 없이도 바로 접근하여 사용할 수 있다. 하지만 인스턴스 변수는 생성된 객체마다 하나씩 존재하는 변수이기 때문에 다른 객체에서는 해당 객체에 대한 참조 없이는 접근할 수 없다.
 
클래스 변수와 인스턴스 변수를 소스 코드로 살펴보면 다음과 같다.

1) 클래스 변수
ClassTest 클래스에 정의되어 있는 클래스 변수인 a 와 b 를 외부에서 접근할 경우에는 ClassTest 클래스에 대한 객체를 생성할 필요 없이 바로 ClassTest.a 와 ClassTest.b 와 같이 접근하면 된다.

class
ClassTest {
    static int a;
    staticString b;
}


2) 인스턴스 변수
InstanceTest 클래스에 선언되어 있는 인스턴스 변수인 a 와 b 를 외부에서 접근할 경우에는 반드시 InstanceTest 클래스에 대한 객체를 생성한 후 접근해야 한다. 그렇기 때문에 a 와 b 에 접근하는 코드는 (new InstanceTest()).a 와 (new InstanceTest()).b 가 된다.
 
class InstanceTest {
    int a;
    String b;
}


3.5.3  디폴트 값
값이 설정되지 않은 멤버 변수는 자동적으로 디폴트 값으로 초기화가 이루어진다. 디폴트 값을 살펴보면 다음과 같다.

표 3-3-3-1 디폴트 값
3-5-3-1.PNG
※ reference type 은 String, Vector 등 자바의 참조형을 의미한다.

멤버 변수가 아닌 자동 변수는 디폴트로 초기화가 되지 않기 때문에 초기화를 하지 않고 사용하면 에러가 발생함으로 주의해야 한다.

class
Test {
    int memberA; //멤버 변수
   
    // 정상
    public voidtestMember() {   
        int Sum = memberA + 1;
       
        System.out.println(Sum);
    }
 
    //에러 발생
    public voidtestAutomatic() {
        int automaticA; //자동 변수
       
        int Sum = automaticA + 1; //에러 발생
       
        System.out.println(Sum);
    }
}


3.5.4  접근 범위
마지막으로 변수의 접근 범위에 대해서 알아보도록 하자. 이전에 살펴보았듯이 클래스 변수는 모든 인스턴스들이 객체 생성없이 접근할 수 있기 때문에 가장 큰 접근 범위를 가진다. 그리고 인스턴스 변수는 클래스에 선언되어 인스턴스마다 따로 소유되기 때문에 클래스 변수보다는 작은 접근 범위를 가진다. 자동 변수의 일종인 매개 변수는 메소드 시작부터 메소드 종료까지 유효하기 때문에 선언된 시점부터 유효한 자동 변수보다 더 넓은 접근 범위를 가지고 있다. 이러한 변수별 접근 범위를 그림으로 표현하면 다음과 같다.

그림 3-5-4-1 변수 접근 범위
 3-5-4-1.PNG


3.6  생성자(Constructor)
생성자(Constructor)란 클래스 초기화를 위한 특별한 메소드이다. 일반적으로 메소드는 객체 생성시 자동으로 호출되지 않지만 생성자는 객체 생성시 자동으로 호출되어 객체가 프로그램에서 사용될 수 있도록 메모리 할당, 변수 초기화 등의 여러 작업을 한다. 생성자의 특징을 정리하면 다음과 같다.

생성자(Constructor) 특징
1. 클래스의 이름과 동일하며 리턴형을 가지지 않는다.
2. 객체 생성시 한 번만 수행된다.
3. final, abstract, native, synchronized 제한자와 함께 선언될 수 없다.
4. 메소드와 유사하지만 메소드처럼 호출 할 수 없다.
5. 매개 변수를 다르게 설정하면 생성자를 여러 개 선언할 수 있다.
6. 생성자를 정의하지 않으면 디폴트 생성자가 자동으로 추가된다.

생성자의 특징을 살펴봤으니 이제 소스 코드를 통해 생성자를 선언하는 방법을 살펴보도록 하겠다.

생성자(Constructor) 예제
public
classConTest {
    privateString name;
 
    //생성자 1
    publicConTest() {
    }
   
    //생성자 2
    publicConTest(String name) {
        this.name = name;
    }
}

위의 소스 코드에는 두 개의 생성자가 선언되어 있다. 첫 번째 생성자는 어떤 기능도 수행하지 않는 생성자이고 두 번째 생성자는 생성자의 매개 변수의 값을 ConTest 클래스의 String 변수 name 에 할당하는 생성자이다. 이 코드를 봤을 때 생성자의 형식은 리턴형이 선언되어 있지 않다는 것을 제외하고는 메소드와 매우 유사하다는 것을 알 수 있다. 이와 같이 선언된 생성자를 호출하기 위해서는 new 연산자를 사용해야 한다. 생성자와 유사한 메소드는 new 연산자가 아닌 객체를 생성한 후 객체의 참조를 통해 해당 메소드를 호출하면 되지만 생성자는 이와는 다르게 new 연산자에 의해 자동적으로 호출된다.

생성자(Constructor) 호출
public classTest {
    public static voidmain(String[] args) {
        ConTest ct1 = new ConTest(); //생성자 1 호출
        ConTest ct2 = new ConTest("con"); //생성자 2 호출
    }
}
 

3.7  메소드(Method)
객체는 상태와 행동을 표현하기 위한 변수와 메소드로 구성되며 변수는 객체의 상태 정보를 저장하기 위해 사용되고 메소드는 상태를 얻거나 변경하기 위해 사용된다. 

메소드(Method) 특징
1. 코드의 중복을 피하며 재사용성을 높인다.
2. 메소드는 시그니처(Signature)로 구분된다. 
3. 메소드에는 제한자(public, private, protected, static, final, synchronized 등)가 선언될 수 있다.
4. 메소드를 통해 다형성(Polymorphism)을 구현할 수 있다.
5. public static void main(String[] args)로 선언된 메소드는 자바가상머신이 어플리케이션 시작을 위해 가장 먼저 호출하는 메소드이다.

 
[TIP&TECH]
시그니처(Signature)는 메소드의 리턴형(Return Type), 메소드명(Method Name), 매개 변수(Parameter)를 말한다.


3.7.1  메소드의 종류
변수에 인스턴스 변수와 클래스가 변수가 있듯이 메소드에도 인스턴스 메소드(Instance Method)와 클래스 메소드(Class Method)가 있다.

그림 메소드 종류
3-7-1-1.PNG

인스턴스 메소드는 static 제한자가 선언되지 않은 메소드로서 보통 메소드라고 하면 인스턴스 메소드를 가리키며 클래스 메소드는 static 제한자가 선언된 메소드로서 정적 메소드(Static Method)라고도 한다. 결국 인스턴스 메소드와 클래스 메소드의 차이는 static 제한자가 있느냐 없느냐이기 때문에 메소드의 차이는 static 제한자의 특성에 따른다고 볼 수 있다. 일단 이 메소드들이 어떻게 생겼는지 소스 코드를 보도록 하자.

인스턴스 메소드(Instance Method)
 public class Test {
    public int add(int a, int b) {
        return a + b;
    }
} 

클래스 메소드(Class Method)
public class Test {
    public static int add(int a, int b) {
        return a + b;
    }
}

static 제한자에 대해서는 [4.5 static 제한자(static Modifier)]에 자세히 나와 있으니 이를 참고하기로 하고 여기서는 인스턴스 메소드와 클래스 메소드의 특징에 대해서 간단히 정리해보도록 하자. 

인스턴스 메소드(Instance Method)
1. static 제한자를 선언하지 않은 메소드를 말한다.
2. 인스턴스 메소드는 인스턴스 변수와 인스턴스 메소드에 바로 접근할 수 있다.
3. 인스턴스 메소드는 클래스 변수와 클래스 메소드에 바로 접근할 수 있다.


클래스 메소드(Class Method)
1. static 제한자를 선언한 메소드를 말한다.
2. 클래스 메소드는 클래스 변수와 클래스 메소드에 바로 접근할 수 있다.
3. 클래스 메소드에서 인스턴스 변수와 인스턴스 메소드에 접근하기 위해서는 해당 객체의 레퍼런스가 필요하다.
4. 클래스 메소드에서는 this 키워드를 사용할 수 없다.
※ 우리가 이전에 작성했던 main 메소드가 클래스 메소드의 대표적인 예이다.


3.7.2  main 메소드
자바에는 프로그램 시작을 위해 반드시 작성해야 하는 메소드가 있다. 이 메소드는 main 메소드로서 항상 정해진 형식으로 선언해야 한다. 그렇지 않을 경우 자바가상머신은 main 메소드를 인식하지 못해 프로그램을 시작하지 못한다. 다음은 main 메소드의 형식을 보여준다.

코드) main 메소드
public classTest {
    public static voidmain(String[] args) {
           //...
    }
}
 

main 메소드의 접근 제한자는 어떤 외부 클래스에서도 호출할 수 있도록 public 제한자로, 객체 생성 없이 main 메소드를 바로 호출할 수 있도록 static 제한자로 선언해야 한다. 그리고 이 메소드는 어떤 값도 반환하지 않기 때문에 void 로 선언해야 한다. 마지막으로 사용자 입력값을 처리하기 위해 String[] args 가 선언되어야 한다. 이때 args 는 단순한 변수명이기 때문에 어떤 이름으로 선언해도 무방하다.

여기서 여러분들은 public 과 static 제한자가 어떤 것인지 궁금해 할 것이다. 이에 대해서는 차후에 다시 설명하도록 하겠으니 여기서는 main 메소드는 반드시 public static void 로 선언되어야 한다는 것만 기억하도록 하자.

마지막으로 main 메소드를 사용하는 소스 코드를 살펴보도록 하겠다. 이 소스 코드는 사용자로부터 두 개의 문자열을 입력받아 화면에 출력한다.

코드) main 메소드 예제
public classTest {
    public static voidmain(String[] args) {
        if (args.length != 2) {
            System.out.println("두 개의 문자열을 입력해주세요!!");
            return;
        }
 
        System.out.println("1: " + args[0]);
        System.out.println("2: " + args[1]);
    }
}

코드) main 메소드 예제 실행 결과
c:\work>javac Test.java
c:\work>java Test easy java
1: easy
2: java

 

3.7.3  오버로딩(Overloading)
오버로딩(Overloading)이란 한 클래스 내에서 동일한 이름의 메소드를 여러 개 정의하는 것을 말한다. 오버로딩을 통해 메소드의 이름은 동일하면서 매개 변수의 개수나 데이터형이 서로 다른 메소드들을 여러 개 정의할 수 있다. 이렇게 정의된 대표적인 메소드가 우리가 자주 사용하는 println() 메소드이다. 이 메소드는 매개 변수의 데이터형에 상관없이 화면에 해당 값을 출력하는 기능을 가진다. 자바 API 에 정의된 println() 메소드를 살펴보면 다음과 같다. 

void println()
void println(boolean x)
void println(char x)
void println(char[] x)
void println(int x)
void println(long x)
void println(float x)
void println(double x)
void println(String x)
void println(Object x)

※ 직접 이 메소드들을 확인하고 싶다면 자바 API 에서 java.lang.System 클래스의 out 변수를 클릭하면 된다.

println() 메소드처럼 오버로딩을 적용하여 메소드를 작성하면 동일한 메소드명으로 다양한 데이터를 받아서 처리할 수 있다. 이 메소드를 사용하는 간단한 예제 코드를 보도록 하자.

class
Test {    
    public static void main(String[] args) {
        System.out.println(10);       

        System.out.println("test");
    }
}


오버로딩을 하기 위해서는 다음과 같은 규칙을 반드시 지켜야 한다. 만약 다음과 같은 규칙을 지키지 않고 메소드를 선언하면 메소드가 오버로딩된 것이 아니라 단순히 메소드가 선언된 것에 불과하다.
 
오버로딩(Overloading) 규칙
1. 메소드는 동일한 이름으로 선언되어야 한다.
2. 매개 변수의 개수나 데이터형이 서로 달라야 한다.


오버로딩 규칙을 적용해 메소드를 선언하면 다음과 같다.

코드) 오버로딩(Overloading) 예제
public classOverloadingTest {
    public intadd(int a, int b) {
        return a + b;
    }

    
public float add(float a, float b) {
        return a + b;
    }

    
public doubleadd(double a, double b, double c) {
        return a + b + c;
    }
}

OverloadingTest 클래스에는 오버로딩 규칙을 적용해 작성된 3개의 메소드가 선언되어 있다. 모두 같은 이름을 가졌기 때문에 어떤 매개 변수가 들어오는지에 따라 호출되는 메소드가 달라진다. int 형 매개 변수가 지정되면 첫 번째 메소드가 호출되며 float 형 매개 변수가 지정되면 두 번째 메소드가 호출된다. 그런데 만약 a, b 변수 모두 long 형으로 지정되면 어떤 메소드가 호출될까? 이때는 long 형을 표현할 수 있는 float 형 매개 변수를 가진 두 번째 메소드가 호출된다. 


3.7.4  오버라이딩(Overriding)
오버라이딩(Overriding)은 부모 클래스에 이미 선언되어 있는 메소드를 하위 클래스에서 재정의하는 것을 말한다. 오버라이딩은 부모 클래스의 형질을 물려받았지만 부모 클래스의 메소드를 그대로 사용하지 않고 특정 기능을 추가하여 사용거나 새로 정의하여 사용하고자 할 때 사용하는 방법이다. 오버로딩과 마찬가지로 오버라이딩을 하기 위해서는 다음과 같은 규칙을 지켜야 한다.

오버라이딩(Overriding) 규칙
1. 상위 클래스의 메소드 이름, 리턴형, 매개 변수의 개수, 데이터형이 일치해야 한다.
2. 접근 제한자는 범위가 같거나 더 넓은 접근 제한자로 선언해야 한다.
3. 상위 클래스에서 private, final 접근 제한자로 선언된 메소드는 오버라이딩할 수 없다.
4. 상위 클래스에서 static 제한자로 선언된 메소드를 오버라이딩할 때는 반드시 static 제한자를 선언해야 한다.

오버라이딩 규칙을 적용해 메소드를 선언하면 다음과 같다.

코드) 오버라이딩(Overriding) 예제
public classSuperClass {
    public intadd(int a, int b) {
        return a + b;
    }
 
    public static longadd2(long a, long b) {
        return a + b;
    }
}

public
classSubClass extends SuperClass {
    public intadd(int a, int b) {
        return a - b;
    }

    
public static longadd2(long a, long b) {
        return a - b;
    }
}
 
이 소스 코드에서 SubClass 는 SuperClass 를 상속하고 있다. 그렇기 때문에 SubClass 에서 add() 메소드를 선언하지 않아도 SuperClass 의 add() 메소드를 사용할 수 있다. 하지만 이 코드에서는 상위 클래스의 add() 메소드를 하위 클래스인 SubClass 에서 오버라이딩하고 있다. 그렇기 때문에 하위 클래스의 add() 메소드를 호출하면 더하기 연산이 수행되는 것이 아니라 빼기 연산이 수행된다. 마찬가지로 add2() 메소드도 오버라이딩 되어 있다. 다만 이 메소드는 상위 클래스에 static 으로 선언되어 있기 때문에 하위 클래스에서도 static 제한자로 선언되어 있다.



3.8  가변 매개 변수(Varags)
JDK 5.0 에 추가된 가변 매개 변수(Varargs, 가변 인수라고도 함)는 변하기 쉬운(Variable)과 매개 변수(Arguments)를 합쳐서 만든 용어로서 매개 변수가 변할 수 있다라는 것을 함축하고 있다. 용어 이름에서 알 수 있듯이 매개 변수를 가변적으로 처리할 수 있다는 것은 배열이나 컬렉션을 사용하지 않고도 여러 인수를 메소드에 넘겨줄 수 있다는 것을 의미한다. 

[TIP&TECH]
메소드에 선언되어 있는 변수를 매개 변수(Parameter), 이 변수를 통해 실제 넘어오는 값을 인수(Arguments, 인자라고도 함)라고 이 둘을 서로 구분한다. 하지만 이 둘을 구분하지 않고 동일하게 매개 변수라고 해도 된다. 왜냐하면 Parameter 와 Arguments 는 형식 매개 변수냐 실 매개 변수냐의 차이일 뿐, 모두 매개 변수이기 때문이다.

다음 코드를 보자. 다음은 args 매개 변수로 넘어온 값에 따라 화면에 출력하는 변수의 개수를 다르게 하여 화면에 출력하기 위한 코드이다. 이 코드에서 print() 메소드를 여러분이 작성해야 한다면 어떻게 작성하겠는가?

public class Test {
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        int c = 3;
       
        if (args[0].equals("1")) {
            print(a);
        } else if (args[0].equals("2")) {
            print(a, b);
        } else if (args[0].equals("3")) {
            print(a, b, c);
        }
    }
}


대부분이 print() 메소드를 다음처럼 작성했을 것이다. 이 방법이 잘못된 것은 아니지만 좀 불편해 보이지 않는가?

public static void print(int a) {
    System.out.println(a);
}

public static void print(int a, int b) {
    System.out.println(a);
    System.out.println(b); 
}

public static void print(int a, int b, int c) {
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
}

이렇게 메소드를 오버로딩(overriding)해서 작성하면 원하는 결과를 얻을 수 있지만 매개 변수의 수가 4개, 5개 이상을 넘어가게 되면 해당 매개 변수의 개수를 처리할 수 있는 메소드도 더 추가되어야 한다. 이러한 불편함을 없앨 수 있는 방법이 바로 가변 매개 변수이다. 가변 매개 변수는 "..."를 사용하여 선언할 수 있으며 이를 사용하면 매개 변수의 수가 얼마나 증가하느냐에 상관 없이 하나의 메소드에서 모두 처리할 수 있다. 위 코드를 가변 매개 변수를 사용해서 변경하면 다음과 같다.

public static void print(int ... vars) {
    for (int var : vars) {
        System.out.println(var);
    }
}
※ 이 코드에서 사용한 for문은 향상된 for문이다. 이에 대해서는 "6장 제어문"에서 살펴보기 바란다.

메소드를 오버로딩하는 것보다 가변 매개 변수를 사용하는 것이 코드를 더 짧고 이해하기 쉽게 한다. 이러한 가변 매개 변수의 구조를 정리하면 다음과 같다.

3-8-1.PNG
사용 예)
public static void print(int ... args) {}
private void print(String ... vars) {}
String process(String ... names) {}


3.9  리터럴(Literal)
리터럴(Literal)은 대입문의 오른쪽에 위치하는 값으로서 개발자가 변수에 값을 대입하기 위해 선언하는 값을 말한다. 다음 코드에서 10, 'a', "java"를 리터럴이라고 한다.

코드) 리터럴
int i = 10;
char c = 'a';
String s = "java";

이러한 리터럴은 크게 기본 데이터형과 문자열로 분류할 수 있다.

그림 리터럴(Literal) 종류
 
3-9-1.png


3.10  정적 임포트(Static Import)
우리가 일반적으로 클래스를 사용하기 위해 선언하는 임포트(import)와 비슷한 기능을 하는 정적 임포트가 JDK 5.0 에 새로 추가되었다. 이름에서 알 수 있듯이 정적 임포트도 무언가를 프로그램에서 사용하기 위해 선언한다. 먼저 일반적인 임포트를 사용하는 코드를 보도록 하자.

코드)
import java.util.ArrayList;
 
public class Test {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
       
        java.util.Vector vec = new java.util.Vector();
    }
}

소스 코드는 java.util 패키지의 ArrayList 클래스와 Vector 클래스를 사용하고 있다. 여기서 ArrayList 클래스는 임포트를 사용하였기 때문에 main() 메소드 내에서는 전체 패키지명을 선언하지 않았다. 하지만 Vector 클래스는 임포트문을 사용하지 않았기 때문에 main() 메소드 내에서 Vector 의 전체 패키지명을 선언하고 있다. 이 코드를 통해서 우리는 임포트는 패키지 명을 사용하지 않고 해당 클래스를 사용할 수 있게 해준다는 것을 알 수 있다. 그러면 정적 임포트는? 아직 정적 임포트가 어떤 기능을 하는지는 살펴보지 않았지만 다음 코드를 보면 정적 임포트가 무엇인지 감이 잡힐 것이다.

코드)
import java.lang.Integer;
import static java.lang.Integer.MAX_VALUE;
 
public class Test {
    public static void main(String[] args) {
        int max = MAX_VALUE;
        int min = Integer.MIN_VALUE;
    }
}

이 코드를 보면 정적 임포트로 Integer 클래스의 정적 변수인 MAX_VALUE 를 임포트하고 있다. 그래서 main() 메소드에서는 이 변수의 클래스명을 지정하지 않고도 사용할 수 있다. 하지만 정적 임포트로 임포트하지 않은 MIN_VALUE 는 해당 클래스명을 선언해야 한다. 이 코드를 통해 여러분은 정적 임포트는 정적 변수를 임포트해서 해당 클래스명을 지정하지 않고도 정적 변수를 사용할 수 있게 한다는 것을 알았을 것이다. 추가적으로 정적 임포트는 정적 변수에만 사용할 수 있는 것은 아니다. static 으로 선언된 정적 메소드에도 사용할 수 있다. 정적 메소드를 임포트하는 것은 정적 변수를 임포트하는 것이랑 동일하다.

코드)
import
static java.lang.Math.abs;
 
public class Test {
    public static void main(String[] args) {
        int a = abs(-10);
    }
}

정리하면, 일반 임포트(import)는 패키지명을 선언하지 않고도 클래스를 사용할 수 있게 하는 것이고 정적 임포트(static import)는 클래스명을 선언하지 않고도 정적 변수와 정적 메소드 같은 정적 멤버(static member)를 사용할 수 있게 하는 것이다.

정적 임포트의 구조를 정리하면 다음과 같다.

3-10-1.PNG

정적 임포트를 사용한 간단한 예제 코드를 작성하면 다음과 같다.
import static java.lang.Math.*;      //Math 클래스의 모든 메소드 임포트
import static java.lang.Math.max;   //Math 클래스의 max 메소드 임포트
import static java.lang.Math.pow;   //Math 클래스의 pow 메소드 임포트


3.11  타입 안전 열거형(Typesafe enums)
타입 안전 열거형(Typesafe enums)은 기존의 열거형이 타입에 안전하지 못했던 것을 개선하여 타입에 안전하도록 JDK 5.0 부터 추가한 기능이다. 먼저 상수를 이용한 기존의 열거형을 보도록 하자.

코드) 
public class Test {
    public static void main(String[] args) {
        int selMovie = 1; //고객이 선택한 영화 종류 번호
        int loanDay = 0; //대여일
       
        //고객이 선택한 영화가 액션이라면
        if (selMovie == Comics.ACTION) {
            //대여일은 1
            loanDay = 1;
        } else {
            //대여일은 3
            loanDay = 3;
        }       
    }
}
 
//만화 종류 열거형
interface Comics {
    public static final int FANTASY = 0;
    public static final int ACTION = 1;
    public static final int DRAMA = 2;
    public static final int SPORTS = 3;
}
 
//영화 종류 열거형
interface Movie {
    public static final int COMEDY = 0;
    public static final int DRAMA = 1;
    public static final int HORROR = 2;
    public static final int ACTION = 3;
}
※ 
상수를 이용한 열거형이기 때문에 고객이 선택한 영화 종류 번호를 만화 종류 열거형과 비교해도 에러가 발생하지 않음.

기존의 열거형은 열거형이라고 하기 보다는 단순히 인터페이스에 상수를 선언한 것에 불과하다. 그래서 인터페이스에 선언된 상수들의 의미에 상관 없이 해당 상수들이 갖고 있는 숫자만 일치하면 해당 상수의 의미와 동일한 것으로 프로그램이 판단하는 문제가 있었다. 이를 타입에 안전하지 않다고 하며 이를 개선한 것이 타입 안전 열거형이다. 타입 안전 열거형을 사용하여 위의 코드를 변경해 보도록 하자. 

public
class Test {
    public static void main(String[] args) {       
        Movie selMovie = Movie.DRAMA; //고객이 선택한 영화 종류 번호
        int loanDay = 0; //대여일       

        
//고객이 선택한 영화가 액션이라면
        if (selMovie == Movie.ACTION) {
            //대여일은 1
            loanDay = 1;
        } else {
            //대여일은 3
            loanDay = 3;
        }       
    }
}
 
//만화 종류 타입 안전 열거형
enum Comics {FANTASY, ACTION, DRAMA, SPORTS};
 
//영화 종류 타입 안전 열거형
enum Movie {COMEDY, DRAMA, HORROR, ACTION};

※ Movie selMovie = Movie.DRAMA : 고객이 선택한 영화 종류도 타입 안전 열거형으로 설정
※ selMovie == Movie.ACTION : 영화 타입 안전 열거형과 비교하지 않을 경우 컴파일 에러 발생


기존의 열거형을 사용하면 열거형의 타입이 다르더라도 정상적으로 컴파일되고 실행되지만 타입 안전 열거형을 사용하면 열거형의 타입을 다르게 사용할 경우 바로 컴파일 에러가 발생한다. 이렇게 컴파일 시간에 오류를 찾아낼 수 있다는 것은 실제 실행 중에는 더 견고하게 동작할 수 있다는 것을 의미한다. 반면에 기존 열거형을 사용할 경우에는 프로그램 실행 중에도 에러가 발생하지 않으므로 오랜 시간이 지난 후에야 프로그램이 이상하게 동작하는 것을 발견할 위험성도 있다. 



지금까지 살펴본 타입 안전 열거형의 구조를 정리하면 다음과 같다.

3-11-1.PNG

타입 안전 열거형을 사용한 간단한 예제 코드를 작성하면 다음과 같다.
enum Season {SPRING, SUMMER, AUTUMN, WINTER}
enum Car {SONATA, AVANTE, ACCENT, WINSTORM}


3.12  어노테이션(Annotations)
어노테이션은 자바에서 메타데이터를 사용하기 위한 기능이다. 어노테이션은 패키지, 생성자, 메소드, 변수 등에 선언할 수 있는 변경자(modifier)로서 내장(Builtin) 어노테이션을 사용할 수도 있으며 직접 커스텀(Custom) 어노테이션을 작성하여 사용할 수도 있다. 이 장에서는 쉽게 사용해 볼 수 있는 내장 어노테이션에 대해서 살펴보도록 하겠다.

[TIP&TECH]
메타데이터(Metadata)는 데이터에 대한 데이터라는 의미로서 문서화, 컴파일러 체크, 코드 분석 등에 유용하게 사용된다.

어노테이션의 표기법은 문서화 주석을 선언하듯이 어노테이션 이름 앞에 @(at)를 붙이면 된다.
@annotation_name

이러한 어노테이션의 용도를 간단히 정리하면 다음과 같다.

1) 컴파일러에게 정보 제공
    컴파일 시간에 에러를 검사하거나 경고를 감추게 하기 위해 사용할 수 있다.

2) 컴파일 시간과 디플로이 시간 처리
    어노테이션 정보를 이용해 코드, XML 파일 등을 생성할 수 있다.
   
3) 실행 시간 처리
    몇몇 어노테이션은 실행 시간에 검사 목적으로 사용될 수 있다.



3.12.1  내장 어노테이션(Builtin Annotations)의 종류
내장 어노테이션에는 Override 어노테이션, Deprecated 어노테이션, SuppressWarning 어노테이션이 있다. 이 어노테이션들에 대해서 하나씩 살펴보도록 하겠다.


1) Override 어노테이션(@Override)
Override 어노테이션은 메소드에 선언되어 해당 메소드가 상위 클래스의 메소드를 오버라이드 한다는 것을 명시한다. 그렇기 때문에 이 어노테이션이 선언된 메소드가 상위 클래스의 메소드를 오버라이드하지 않는 경우에는 컴파일시 에러가 발생한다. 다음 코드는 @Override 어노테이션을 사용하여 java.lang.Object 객체에 있는 toString() 메소드를 오버라이드하는 코드이다. 하지만 이 코드에서는 toString() 메소드를 tostring() 메소드로 잘못 선언하였기 때문에 컴파일 시간에 오버라이드가 되지 않았다는 에러가 발생한다.

[TIP&TECH]
java.lang.Object 는 모든 클래스의 최상위 클래스로서 명시적으로 상속하지 않아도 자동적으로 상속되는 클래스이다.

코드)
class
AnoTest {
    @Override
    public String tostring() {
        return super.toString() + " annotation";
    }
}

C:\Test>javac AnoTest.java
Test.java:2: method does not override a method from its superclass
    @Override
     ^
1 error

Override 어노테이션을 선언하지 않았을 경우에는 위와 같이 컴파일 시간에 에러가 발생하지 않는다. 그렇기 때문에 오버라이드해서 java.lang.Object 클래스에 있는 toString() 메소드의 기능이 아닌 AnoTest 클래스만의 toString() 메소드로 처리하고자 했던 기능을 사용할 수 없게 된다. 이는 차후 프로그램 실행 시간에 프로그램이 원하는 데로 동작하지 않는 원인을 찾기 위한 디버깅 시간을 소비해야 한다는 것을 의미한다. 그렇기 때문에 명시적으로 이 메소드는 오버라이드 한다는 것을 어노테이션을 통해 자바 컴파일러에게 알려준다면 메소드 이름을 잘못 선언하여 발생하는 문제를 미연에 방지할 수 있다. 


2) Deprecated 어노테이션(@Deprecated)
Deprecated 어노테이션은 더 이상 사용되지 말아야 하는 메소드에 선언한다. 그렇기 때문에 이 어노테이션이 선언된 메소드를 호출할 경우에는 컴파일 시간에 경고가 발생한다. 

다음 코드를 보자. 이 코드에서 AnoTest 클래스의 tostring() 메소드에 @Deprecated 어노테이션이 선언됐는데도 불구하고 Test 클래스에서 해당 메소드를 호출하고 있다. 그렇기 때문에 이 코드를 컴파일하면 경고 메시지가 발생한다.

코드)
public class Test {
    public static void main(String[] args) {
            AnoTest ano = new AnoTest();
            System.out.println(ano.tostring());
    }
}
 
class AnoTest {
    @Deprecated
    public String tostring() {
        return super.toString() + " annotation";
    }
}

C:\Test>javac -Xlint Test.java
Test.java:6: warning: [deprecation] tostring() in AnoTest has been deprecated
            System.out.println(ano.tostring());
                                  ^
1 warning

[TIP&TECH]
javac 의 ?Xlint 옵션은 컴파일 시간에 발생한 경고 메시지에 대한 상세 정보를 얻고자 할 때 사용한다. 이 옵션은 ?Xlint 와 같이 단독으로 사용할 수도 있고 ?Xlint:deprecation 나 -Xlint:unchecked 와 같이 얻고자 하는 특정 유형을 지정하여 사용할 수도 있다.


3) SuppressWarnings 어노테이션(@SuppressWarnings)
SuppressWarning 어노테이션은 이름에서 알 수 있듯이 경고를 감추기 위한 어노테이션이다. 이 어노테이션은 클래스나 메소드에 선언할 수 있다.

SuppressWarnings = suppress(감추다) + warnings(경고)

SuppressWarning 어노테이션은 자바 언어 스펙에 지정된 unchecked 와 deprecation 와 같은 경고문을 감출 수 있다. 다음은 SuppressWarning 어노테이션을 사용하는 다양한 방법을 보여준다.

@SuppressWarnings("unchecked")
@SuppressWarnings("deprecation")
@SuppressWarnings(value={"unchecked"})
@SuppressWarnings(value={"deprecation"})
@SuppressWarnings(value={"unchecked", "deprecation"})


이제 SuppressWarning 어노테이션을 사용하는 다음 예제 코드를 살펴보도록 하자. 다음 코드를 저장하고 컴파일하면 어떻게 될까? unchecked 경고 메시지가 출력된다. 이 경고 메시지가 출력되는 이유는 List 컬렉션에 저장될 타입을 지정하지 않았기 때문이다.

코드)
public
class Test {
    public static void main(String[] args) {
            java.util.List list = new java.util.ArrayList();
            list.add("1");
            list.add("2");
    }
}

C:\Test>javac -Xlint Test.java
Test.java:4: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
            list.add("1");
                    ^
Test.java:5: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
            list.add("2");
                    ^
2 warnings

이러한 경고 메시지를 보기 싫은 경우에는 SuppressWarning 어노테이션을 클래스나 메소드에 선언하면 된다. 만약 다음과 같이 선언했는데도 불구하고 해당 경고가 사라지지 않는다면 설치된 JDK 의 버전을 확인해야 한다. 왜냐하면 JDK 1.5.0_06 이전 버전에서는 SuppressWarning 어노테이션을 지원하지 않았기 때문이다.

@SuppressWarnings
(value={"unchecked"})
//@SuppressWarnings("unchecked") 와 같이 사용할 수도 있음.
 
public class Test {
    public static void main(String[] args) {
            java.util.List list = new java.util.ArrayList();
            list.add("1");
            list.add("2");
    }
}

C:\Test>javac -Xlint Test.java
※ ?Xlint 는 unchecked 에 대한 상세 정보를 보기 위한 옵션이다.

이 글은 무단전제나 무단배포가 금지된 글입니다. 공유하고자 한다면 제목과 링크만 공유하기 바랍니다.


로그인 창이 있는 "정보 수정"에서
서명 이쁘게 등록해보세요 ^^

라쿠드 2016-09-24 (토) 18:43
감사합니다
댓글주소
indist 2016-10-03 (월) 03:35


정신 없네요..뭐가뭔지



댓글주소
처음  1  2
이전글  다음글  목록 글쓰기

총 게시물 25건, 최근 0 건 안내 RSS
번호 분류 제목 추천 조회
25 0.소개  0.1 머리말 37 29 10160
24 0.소개  0.2 목차 16 10 6794
23 1.기본 지식편  0장 기본 지식편 27 30 10375
22 1.기본 지식편  1장 객체지향 프로그래밍 33 25 14040
21 2.코드 지식편  1장 0. 변수, 데이터형 20 15 7419
20 2.코드 지식편  1장 1. 가장 빠른 변수는 지역 변수이다. 19 14 7655
19 2.코드 지식편  1장 2. 멤버 변수를 중복 초기화하지 않는다. 17 11 7592
18 2.코드 지식편  1장 3. 멤버 변수의 디폴트 값에 대해 알아야 한다. 17 7 7802
17 2.코드 지식편  1장 4. 블록 내에서 사용할 변수는 지역 변수로 선언해야 한다. 16 12 6748
16 2.코드 지식편  1장 5. 자동 변수를 사용할 때는 항상 초기값을 설정해야 한다. 19 10 7385
15 2.코드 지식편  1장 6. 상수는 되도록 기본 데이터형을 사용해야 한다. 16 11 7062
14 2.코드 지식편  1장 7. 상수는 사용시 주의해야 한다. 20 11 6697
13 2.코드 지식편  1장 8. 변수는 되도록 사용 시점에 선언해야 한다. 15 7 5560
12 2.코드 지식편  1장 9. 객체보다는 기본 데이터형을 사용해야 한다. 13 7 5838
11 1.기본 지식편  1장 객체지향 프로그래밍 체크 포인트 17 9 6162
10 1.기본 지식편  2장 소스 코드 구성 28 15 10219
9 1.기본 지식편  2장 소스 코드 구성 체크 포인트 8 8 5571
8 1.기본 지식편  3장 클래스 구성 22 10 9934
7 1.기본 지식편  3장 클래스 구성 체크 포인트 6 4 5310
6 1.기본 지식편  4장 제한자 11 6 7261
5 1.기본 지식편  4장 제한자 체크 포인트 4 3 4972
4 1.기본 지식편  5장 연산자 11 7 9780
3 1.기본 지식편  5장 연산자 체크 포인트 4 5 5696
2 0.소개  스피드 자바의 오프라인 서적의 평. 11 8 6505
 


Copyright ⓒ www.androidside.com. All rights reserved.
채팅 권한: 글쓰기 1개
2레벨 이상만 대화 가능
공개 채팅: 평일 !(9시 ~ 17시),토,일
안사2 변경사항 보러가기 챗방이 잘 안보이면 크롬에서 접속해주세요
챗방 숨기기 |  챗방 보이기