제2장 자바 언어 기초
2.1 자바 식별자 와 키워드
자바 식별자 자바 식별자 (identifier) 작성규칙 클래스 이름, 메소드 이름, 변수 이름 등 유니코드를 사용한다 문자와 숫자의 연속이다 문자로 시작한다 키워드, true, false, null과 같은 철자를 사용할 수 없다 ‘_’, ‘$’ 등으로 시작할 수 있다 대·소문자를 구별한다 길이에 제한이 없다
자바 식별자 올바른 식별자의 예 틀린 식별자의 예 id userName user_name _userName $userName 3d_studio this #arg
키워드 자바의 키워드 주의 abstract default if private throw boolean do implements protected throws break double import public transient byte else instanceof return try case extends int short void catch final interface static volatile char finally long super while class float native switch const for new synchronized continue goto package this 주의 1) const와 goto는 예약어로 지정됐지만 현재 사용되지 않는다. 2) "true", "false", "null" 은 boolean/null 상수로 예약어처럼 사용가능 3) 문자가 자바 문자나 숫자인가를 알아보기 위해서는 Character.isJavaLetterOrDigit() 메소드를 이용할 수 있다. 4) 유니코드에 관한 정보는 http://www.unicode.org/에서 얻을 수 있다.
예제 : id.java 결 과 1 class id { % javac id.java % java id 안녕하세요. 홍길동 님! 2 public static void main(String args[]) { 3 String 이름 = "홍길동"; 4 System.out.println("안녕하세요. " + 이름 +" 님!"); 5 } 6 } 결 과 % javac id.java % java id 안녕하세요. 홍길동 님!
예제 : NameTest.java 클래스, 메소드, 멤버필드의 이름 공간이 분리 클래스, 메소드, 멤버필드의 이름이 동일해도 됨 1 class SameNamePoint int x, y; 2 3 class NameTest { 4 5 static SameNamePoint SameNamePoint(int x, int y) { 6 SameNamePoint p = new SameNamePoint(); . . . 11 public static void main(String[] args) { 12 int SameNamePoint; 13 SameNamePoint[] pa = new SameNamePoint[2]; 14 for (SameNamePoint = 0; SameNamePoint < 2; SameNamePoint++) { 15 pa[SameNamePoint] = new SameNamePoint();
예제 : BreakLabel.java break/continue에서 사용되는 레이블 변수와 다른 이름 공간을 갖는다. 라벨과 변수의 이름이 동일해도 무방 1 class BreakLabel { 2 public static void main(String args[ ]) { 3 i: 4 for (int i = 0; i <= 100; i++) { 5 int j = 0; 6 while (j < 10) { 7 j++; …………...
2.2 데이터 타입
자바 자료 타입
기본 자료 타입 주 의 1) 자바에서는 C언어의 기본 자료 타입에 boolean과 byte라는 타입을 추가 주 의 1) 자바에서는 C언어의 기본 자료 타입에 boolean과 byte라는 타입을 추가 2) 각 자료타입은 클래스의 멤버필드/배열의 컴포넌트는 처음에 생성될 때 디폴트 값으로 초기화된다. 지역 변수인 경우에는 초기화되지 않는다
int 타입 int 타입 예제 : Int.java 32비트 정수 타입으로 -231 ~ 231-1 사이의 값을 가진다. 1 class Int { 2 3 public static void main(String ard[]) { 4 int int1 = 5, int2 = 28; 5 int int3, int4, int5 ; 6 7 int3 = int2 * int1; 8 int4 = int2 / int1; 9 int5 = 25 / int1; 10 11 System.out.println("28 * 5 = "+ int3); 12 System.out.println("28 / 5 = "+ int4); 13 System.out.println("25 / 5 = "+ int5); 14 } 15 }
byte, short 타입 byte와 short도 int와 마찬가지로 정수 타입이다. byte는 -27 ~ 27-1 사이의 값 예제 : Byte.java 1 class Byte { 2 public static void main(String args[]) { 3 byte byte1; 4 5 byte1 = 256; 6 System.out.println("byte1 = "+byte1); 7 } 8 }
float, double 타입 IEEE 754-1985 표준에 따라 표현된다. 두 실수 x, y를 이용해서 연산할 수 있는 예 -0.0과 +0.0, 2개의 0.0을 가진다. 오버플로우(overflow)와 언더플로우(underflow) 발생 가능. 표준에는 유효하지 않은 연산 ( * 0.0, 0.0 / 0.0 등) 결과를 위해 NaN (Not a Number)을 가지고 있다. NaN은 숫자가 아니다. 두 실수 x, y를 이용해서 연산할 수 있는 예
예제 : FloatingOne.java 결 과 1 class FloatingOne { 2 public static void main(String args[]) { 3 float float1; 4 5 float1 = 3.14; 6 } 7 } 결 과 % javac FloatingOne.java FloatingOne.java:5: Incompatible type for =. Explicit cast needed to convert double to float. float1 = 3.14; ^ 1 error
예제 : FloatingFour.java 결 과 1 class FloatingFour { 2 public static void main(String args[]) { 3 int int1; 4 float float1 = 28.0f, float2 = 5; 5 6 int1 = (int)(float1 / float2); 7 System.out.println("(int)(28.0 / 5.0) = "+int1); ………….. 결 과 % java FloatingFour (int)(28.0 / 5.0) = 5
char 타입 char 타입은 16 비트의 부호가 없는 유니코드로 정의 예제: CharOne.java 1 class CharOne { 2 public static void main(String args[]) { 3 char c = 'a'; 4 int int1 ; 5 6 int1 = c; 7 System.out.println("int1 = "+ int1); 8 9 int1 = int1 + 1; 10 System.out.println("int1 = "+ int1); 11 System.out.println("(char)"+ int1 +" = "+ (char)int1); ……… 예제: CharTwo.java 1 class CharTwo { 3 char han = '\ud55c'; 4 char gul = '\uae00’; ……..
boolean 타입 true나 false 값만을 가질 수 있고 다른 타입(예, int)이 boolean 타입으로 변환 불가능. 따라서 C처럼 다음 형태의 프로그램은 작성할 수 없다. .... while( 1 ) { ...... } 작성 예: ..... while(true) {
리터럴 (Literal) 프로그램의 소스에서 직접 값으로 표현된 것 주 의 - 자바에서는 지원하지 않는 C 언어 자료 유형 a = 2; // 2는 int형 리터럴 x = 0xA; // A는 16진수로 표현된 int형 리터럴 o = 055; // 55는 8진수로 표현된 int형 리터럴 b = 5L; // 5는 long형 리터럴 f = 2.0f; // 2.0f는 float형 리터럴 d = 2.0; // 2.0은 double형 리터럴 e = 2.0E4; // double형 리터럴, 2.0 * 104을 의미한다. t = true; // true는 boolean형 리터럴 c = 'd'; // d는 문자형 리터럴 s = "Hello"; // Hello는 문자열 리터럴 주 의 - 자바에서는 지원하지 않는 C 언어 자료 유형 1) 포인터 : 자바에서는 포인터를 지원하지 않는다. 2) struct / union : 자바에서는 struct와 union을 지원하지 않는다. 클래스를 정의해서 struct처럼 사용할 수 있다.
참조 타입 C++과 자바에서 객체를 생성하는 방법 1 int a = 100 ; 2 Car mycar, yourcar; 3 mycar = new Car(); 4 yourcar = mycar;
==과 equals() == 연산자와 equals() 메소드의 차이점 두 연산자의 차이점의 예 == 연산자는 두 변수의 값이 같은가를 물어본다 equals() 메소드는 객체의 내용이 같은가를 물어본다. == 연산자는 기본 자료형이나 레퍼런스에 사용 equals() 메소드는 레퍼런스 타입에서만 사용 두 연산자의 차이점의 예
예제: Equal.java 1 public class Equal { 2 public static void main(String args[]) { 3 String a = new String("abc"); 4 String b = "abc"; 5 String c = b; 6 String d = a; 7 8 StringBuffer e = new StringBuffer("abc"); 9 StringBuffer g = e; 10 11 if(a = = b) { 12 System.out.println("a= =b"); 13 } 14 // if(a = = e) { // 컴파일 에러 15 // System.out.println("a= =e"); 16 // } …………...
예제: Equal.java 결 과 20 if(b.equals(a)) { 21 System.out.println("b.equals(a)"); 22 } 23 if(b.equals(e)) { 24 System.out.println("b.equals(e)"); ……………... 결 과 % java Equal c==b b.equals(a)
문자열 String 클래스로 제공 예 기초 자료 유형이 아님 문자열을 표현하기 위해 자바에서 제공하는 클래스 '+' 연산자는 두 개의 문자열을 접합하는 연산자이다. '+' 연산자를 이용해서 문자열을 접합하는 경우에 String 클래스의 내용이 변경되는 것이 아니라 새로운 객체가 생성 예 String message; // message를 String 타입 변수로 선언. ..... message = "hello "; // message에 "hello " 값을 할당. message += "world !"; // "hello "와 "world !"를 접합해서 // message 변수에 할당
배열 자바에서 배열은 동적으로 생성할 수 있는 클래스 예 배열은 선언 후에 new 연산자를 사용해서 할당하여야 한다. int k[ ]; // int 배열을 선언. int[ ] k 와 동일 위처럼 선언만 한 경우에는 배열을 사용할 수 없다. 사용하기 전에 반드시 new 연산자를 이용해서 배열 생성 "int k[10];" 형태로는 사용할 수 없다. 배열의 인덱스는 0 ~ length - 1까지 사용될 수 있고,
배열의 초기화 예 문자열의 배열을 사용하는 예: int[] k = {1, 2, 3}; 아래와 동일한 의미 k = new int[3]; // k[ ] = new int[3]은 사용할 수 없다. k[0] = 1; k[1] = 2; k[2] = 3; 배열은 기초 타입뿐만 아니라 클래스의 객체도 포함할 수 있다. 문자열의 배열을 사용하는 예: String[] names = new String[50];
예제: Gauss.java 1 class Gauss { 2 public static void main(String[] args) { 3 int[] ia = new int[101]; 4 for (int i = 0; i < ia.length; i++) 5 ia[i] = i; 6 7 int sum = 0; 8 for (int i = 0; i < ia.length; i++) 9 sum += ia[i]; 10 ………...
다차원 배열 예: 다차원 배열 선언 후 new 연산자를 이용해서 배열 생성 int twoDarray[][]; String threeDarray[][][]; 다차원 배열 선언 후 new 연산자를 이용해서 배열 생성 다차원 배열에서 C 언어와 다른 점 (2차원 배열 예) C 언어에서는 배열이 격자 모양으로 가로 세로의 크기가 고정 자바에서는 다양한 형태의 배열을 가질 수 있다.
다차원 배열 예 twoDarray = new int[4][5]; 이것은 4 x 5의 격자 모양의 배열을 만든 것이다. 전체 배열의 크기는 4로 만들고 배열의 각 컴포넌트는 필요한 경우에 동적으로 크기를 결정
예제: MultiDarray.java 1 class MultiDarray { 2 public static void main(String args[]) { 3 char stars[][]; 4 5 stars = new char[6][]; 6 for(int i=0; i < stars.length; i++) { 7 stars[i] = new char[i+1]; 8 for(int j=0; j < stars[i].length; j++) { 9 stars[i][j] = '*'; 10 } ………….
2.3 연산자
연산자 우선 순위
++, -- 연산자 변수의 값을 증가/감소 예: i = 0; System.out.println("++i = " + ++i); i의 값이 증가하고, println() 함수가 수행 System.out.println("i++ = " + i++); i++ = 0이 출력될 것이다. println() 함수가 수행되고 i의 값이 증가
타입 변환 자동 변환 문자열로 타입 변환 예: 배정문(=) 함수 호출 문자열로 형 변환 프로모션(promotion) 다른 자료형이 문자열과 '+' 연산을 하는 경우에 문자열로 타입 변환 예: int j = 10; System.out.println("j = " + j)
프로모션 수 타입이 다른 피연산자에 따라 더 큰 타입으로 자동 형 변환 예: int j = 5; double f = 16.0 + j; j의 값 5는 double 16.0과 덧셈을 위해 5.0으로 자동 형 변환 일반적으로 작은 타입에서 큰 타입으로 형 변환은 자동 정보를 잃어버리지 않기 때문에 큰 타입에서 작은 타입으로의 형 변환은 자동적으로 이루어지지 않음 정보를 잃어버릴 수 있기 때문에 프로그래머가 명시적으로 캐스트 연산자를 사용
참조 타입에서 타입 변환 작은 타입에서 큰 타입으로 변환은 자동 큰 타입에서 작은 타입으로 변환 본래 형이 작은 형인 경우에만 캐스트 연산자를 사용해서 가능
이동 연산자 (>>, >>>, <<) >>는 원하는 비트만큼 우로 이동하는 연산자 123 >> 2라고 하면 123을 오른쪽으로 2비트 이동 >> 연산을 하는 경우에는 부호 확장(sign extension)이 발생 123(10) = 00000000000000000000000001111011(2) 우로 2비트 이동하는 경우에 왼쪽 2비트는 부호 값인 0으로 -123(10) = 11111111111111111111111110000101(2) 우로 2비트 이동하는 경우에 맨 왼쪽 2비트는 부호 값인 1로 >>> 비트 연산자 >>과는 달리 부호 확장이 없고 항상 맨 왼쪽을 0으로 << 비트 연산자 왼쪽으로 이동, 맨 오른쪽 비트는 항상 0으로
예제 주 의 % java Shift 123 >> 2 = 30 -123 >> 2 = -31 -123 >>> 2 = 1073741793 123 << 2 = 492 -123 << 2 = -492 -123 << 32 = -123 주 의 이동 연산자는 정수형(byte, short, char, int, long)에만 적용되고, 연산이 수행되기 전에 int와 long 타입으로 형 변환이 된 후 연산이 이루어짐 주의할 점은 int 형은 32 비트이고, long 형은 64 비트이기 때문에 int 타입을 32 비트 (long은 64 비트) 이상 쉬프트시킨다는 것은 의미가 없 다.
논리 연산자 (&&, ||) && || 단락 회로 논리(Short-circuit logic) 예 논리 연산자 AND || 논리 연산자 OR 단락 회로 논리(Short-circuit logic) if ( 참 || ??) if ( 거짓 && ??) 예 String msg = null; if((msg != null) && (msg.equals("hello")) ...
instanceof, 비트 연산자 instanceof 연산자 비트 연산자 (&, | , ^) 왼쪽에 있는 객체가 오른쪽 클래스의 객체이면 true 아니면 false를 반환한다. if( b1 instanceof Button) ... 비트 연산자 (&, | , ^) 모두 정수형 (byte, short, char, int, long)에 적용 bitwise AND, bitwise OR, bitwise XOR 연산이 수행된다 boolean 형에 적용 논리 연산자 AND, 논리 연산자 OR, 논리 연산자 XOR 수행 &과 |는 단락회로 논리를 사용하지 않음
2.4 제어 구조
if 문 자바의 제어 구조는 C나 C++와 거의 동일 형태 1: 형태 2: if (boolean) { statements; } else { } 형태 2: } else if(boolean) {
예제: HelloSomebody.java 1 class HelloSomebody { 2 3 public static void main (String args[]) { 4 5 System.out.print("Hello "); 6 if (args.length > 0) { 7 System.out.println(args[0]); 8 } 9 else { 10 System.out.println("?????"); 11 } …………. 결 과 % javac HelloSomebody.java % java HelloSomebody CHOI Hello CHOI --> 실행 결과 % java HelloSomebody Hello ????? --> 실행 결과
예제 args[3] java HelloSomebody CHOI KIM T args[0] args[1]
for 문 형태: 예제: HelloFriends.java 결 과 for(init_expr; test_expr2; increment_expr3) { statements; } 예제: HelloFriends.java 1 class HelloFriends { 3 public static void main (String args[]) { 5 int i; 7 System.out.print("Hello "); 8 for (i=0; i < args.length; i++) { 9 System.out.print(args[i]); 10 System.out.print(" "); 11 } 12 System.out.println(); ………. 결 과 % javac HelloFriends.java % java HelloFriends CHOI LEE KIM SONG PARK YANG Hello CHOI LEE KIM SONG PARK YANG --> 실행 결과
while 문 형태: 예제: HelloFriendsWhile.java 결 과 while(boolean) { statements; } 예제: HelloFriendsWhile.java 1 class HelloFriendsWhile { 3 public static void main (String args[]) { 5 int i = 0; 7 System.out.print("Hello "); 8 while(i < args.length) { 9 System.out.print(args[i]); 10 System.out.print(" "); 11 i++; 12 } ………….. 결 과 % javac HelloFriendsWhile.java % java HelloFriendsWhile CHOI LEE KIM SONG PARK YANG Hello CHOI LEE KIM SONG PARK YANG --> 실행 결과
do-while 문 do-while 문은 while문과 비슷하지만 최소 한번은 수 행됨 형태: statements; } while(boolean);
예제: HelloFriendsDoWhile.java 1 class HelloFriendsDoWhile { 3 public static void main (String args[]) { 5 int i = 0; 7 System.out.print("Hello "); 8 do { 9 System.out.print(args[i]); 10 System.out.print(" "); 11 i++; 12 } while(i < args.length); …………. 결 과 % javac HelloFriendsDoWhile.java % java HelloFriendsDoWhile CHOI LEE KIM SONG PARK YANG Hello CHOI LEE KIM SONG PARK YANG --> 실행 결과
switch 문 스위치 문의 expr 부분에는 long을 제외한 정수형 타입 형태: byte, short, char, int 문자열이나 실수형 및 long 등은 expr 부분에 들어갈 수 없다. 형태: switch(expr) { case expr1: statements; break; case expr2: default: }
예제: YesOrNo.java 1 import java.io.*; 3 class YesOrNo { 4 public static void main(String args[]) { 6 System.out.println("Yes/No ?"); 7 try { 8 char c = (char)System.in.read(); 9 10 switch(c) { 11 case 'y': 12 case 'Y': 13 System.out.println("Yes"); 14 break; 15 case 'n': 16 case 'N': 17 System.out.println("No"); 18 break; 19 default: 20 System.out.println("Wrong answer"); 21 break; 22 } 23 }catch(IOException e) { } ………..
break 문 for, while, do, switch 문에서 빠져나갈 때 사용 예제: Break.java 1 import java.io.IOException; 3 class Break { 4 public static void main(String args[]) { 6 System.out.println("Enter 'q' to exit."); 7 quit: 8 for(int i=0; i < 10; i++) { 9 for(int j=0; j < 10; j++) { 10 if(j%7 == 4) { 11 try { 12 int b = System.in.read(); 13 if(b == 'q') 14 break quit; 15 }catch(IOException ioe) {} 16 } else if(j%7 == 6) 17 break; 18 else 19 System.out.print("(" + i +","+j+")"); ……...
continue 문 while, do, for 문에서 continue문 예제: Continue.java 다음은 수행하지 않고 반복문의 조건 부분을 실행한다. 예제: Continue.java 1 class Continue { 2 public static void main(String args[]) { 3 int sum =0; 4 System.out.println("continue 테스트."); 5 6 quit: 7 for(int i=0; i < 10; i++) { 8 for(int j=i; j < 2*i; j++) { 9 System.out.print("("+i+","+j+","+sum+")"); 10 if(j%3 == 0) 11 continue; 12 if(sum > i*10) 13 continue quit; 14 else 15 sum += j; ……...
함수 호출 함수 호출은 값 전달(call-by-value)을 사용한다. 참조타입의 매개변수 클래스, 인터페이스, 배열의 경우 참조를 사용하기 때문에 참조전달(call-by-reference) 효과가 발생
2.5 예외 처리 (Exception Handling)
예외(Exception) 예외 Exception object is a first-class object 예외 (상황): 심각하지 않은 에러 혹은 비정상적 상황 예외 발생 시 계속 수행할 수 있도록 처리해야 한다 Exception object is a first-class object 일반 object처럼 클래스를 이용하여 정의되고 일반 object처럼 사용될 수 있다. 일반 object와 차이점 throw 될 수 있다.
Java에서 예외 선언 자바에서 예외 타입은 클래스로 선언 예외 선언 예외타입은 클래스이다 Exception 클래스나 서브클래스로부터 상속 받아 정의한다. 예외타입은 클래스이다 생성자, 멤버 필드, 메소드 등을 가질 수 있다.
예외 클래스 계층 구조 Object … Throwable Exception Error RuntimeException ClassNotFoundException IllegalAcessException InstantiationException InterruptedException NoSuchMethodException … ArithmeticException NagativeArraySizeException ArrayIndexOutOfBoundsException SecurityException . . .
예외 클래스: 예제 DivideZeroException.java 2 private String reason; 3 1 public class DivideZeroException extends Exception { 2 private String reason; 3 4 DivideZeroException() { 5 reason = "Divide by zero"; 6 } 7 8 public String toString() { 9 return reason; 10 } 11 }
throw exception-object; 예외 발생 예외는 throw문을 이용해서 발생시킨다 throw exception-object; throws와는 다름
예외 발생: 예제 Divider.java 1 public class Divider { 2 3 public Divider() { } 6 7 public int divide(int x) throws DivideZeroException { 8 switch(x) { 9 case 0: 10 throw new DivideZeroException(); 11 case 1: 12 throw new DivideZeroException(); 13 defaults: 14 ; 15 } 16 return (int)(100/(x*(x-1))); 17 } 18 }
예외 처리 예외 발생 시 처리하지 않는 경우 프로그램은 메시지를 내고 종료한다. 메시지는 call stack trace를 포함한다. main 메쏘드부터 호출과정
예외 처리: try-catch 문 구문 구조 try { … } catch (E1 x) { … } … catch (En x) { … } 예외가 발생할 수 있는 문장들을 try문 블록에 기술한다. 예외가 발생하면 해당 매칭되는 catch 문으로 제어가 넘어 간다.
예외 처리: finally 절 try { … } catch (E1 x) { … } finally 절은 옵션 … catch (En x) { … } finally { … } finally문은 예외 발생 여부에 관계없이 항상 수행된다
예외 처리: 예제 TestException.java 1 public class TestException { 2 public TestException() { } 3 4 public static void main(String[] args) { 5 int a; 6 7 Divider t = new Divider(); 8 try { 9 a = Integer.parseInt(args[0]); 10 System.out.println("successful!: "+ t.divide(a)); 11 } catch(DivideZeroException e) { 12 System.out.println("error!!: " + e); 13 } catch(Exception ex) { 14 System.out.println("error!!: " + ex); 15 } . . .
예외 전파 처리되지 않는 예외 전파 호출의 역순으로 처리될 때까지 전파된다. main() 메소드까지 전파된다.
예외 전파: 예제 public class Propagation_Demo { static public void main (String[] args) { Exception_Scope demo = new Exception_Scope(); System.out.println("program beginning"); demo.level1(); System.out.println("program ending"); } // method main } // class Propagation_Demo
class Exception_Scope { public void level3 (int adjustment) { int current = 1; System.out.println("level3 beginning"); current = current / adjustment; System.out.println("level3 ending"); } // method level3 public void level2() { System.out.println("level2 beginning"); level3 (0); System.out.println("level2 ending"); } // method level2 public void level1() { System.out.println("level1 beginning"); try { level2(); } catch (ArithmeticException problem) { System.out.println (problem.getMessage()); problem.printStackTrace(); } System.out.println("level1 ending"); } // method level1 } // class Exception_Scope
예외 종류 검사 예외(checked exception) 비검사 예외(unchecked exception) 컴파일러가 처리 여부를 검사하는 예외 처리되지 않는 검사 예외는 메소드 헤더 부분에 throws를 이용하여 선언 비검사 예외(unchecked exception) RuntimeException로부터 상속 받는 표준 런타임 예외 처리 여부를 컴파일러가 검사하지 않는 예외
예외 명세 처리되지 않은 검사 예외를 메소드 이름 뒤에 명세 throws 절 이용 메소드_이름(…) throws A, B, C { . . . }
컴파일러의 예외 분석 컴파일-시간 예외 분석 발생된 예외가 처리되었는지 아니면 메소드 선언 시 명세 되었는지 컴파일-시간 검사 호출된 메소드에서 처리되지 않는 예외 메소드 선언에 명세된 처리되지 않는 예외 정보를 이용
Java 예외 클래스 예 ArithmeticException ArrayIndexOutofBoundsException 0으로 나누는 경우에 주로 발생하는 예외 상황 ArithmeticException은 RuntimeException으로부터 상속받은 예외 클래스 ArrayIndexOutofBoundsException 배열의 크기보다 큰 원소를 접근하려고 할 때 발생되는 예외 NegativeArraySizeException 배열의 크기가 음수로 된 경우에 발생하는 예외 NullPointerException 생성되지 않은 객체를 이용해서 객체의 멤버를 접근하는 경우에 발생하는 예외