SCJP 강좌 Section 9 java.lang package 문서정보 문서제목 scjp 강좌 : Section 9 java.lang package 파일이름 PJ_scjp_9_0_1.pdf 작성자 신상훈, 김병필 작성일 2002년 1월 10일 버전 0.1 상태 초안 내용정보 예상독자개요 페이지 scjp 취득을원하는 java 초보 java.lang 패키지의 Object / Math class 에관한설명, String과 StringBuffer 클래스의비교 9페이지
java.lang Package lang 패키지에는모든클래스의상위클래스인 Object, 기본형을포함하는 wrapper 클래스, String 클래스, 수학적계산을위한 Math, Thread, Class, Package 등의클래스를포함한다. Object 와 Math 클래스에관해서자세히알아보자. 1. Object class 자바클래스계층에서최상위클래스이다. 아무런클래스도상속받지않은클래스라도실제로는 Object 클래스를상속받게된다. 즉, 모든클래스는 Object 를상속받게된다. Object 형의참조변수는어떠한클래스의참조값도저장할수있다. 클래스의계층에서상위클래스의참조변수는하위클래스의참조형을저장할수있다. primitive 형을 Object 에직접대입할수는없다. wrapper 클래스형태나배열로만들면대입이가능하다. 1.1 Object 의메소드 1) boolean equals(object obj) 두개의객체가같은지를비교한다. 이메소드는두개의객체가동일한객체일때 ( 즉메모리공간의동일한공간에저장된같은메모리일때 ) 만 true 를리턴한다. Button a = new Button("foo"); Button b = new Button("foo"); if(a.equals(b)){ System.out.print("equals"); } 두개의버튼은같은내용을포함하고있지만두개의버튼이저장된실제의위치는다르다. 즉, a 가가리키는메모리번지와 b 가가리키는메모리번지가다르다. 그러므로 "equals" 는출력이되지않는다. Integer a = new Integer(3); Integer b = new Integer(3); if(a.equals(b)){ System.out.print("equals"); } 두번째의코드에서는 "equals" 라는메세지가출력이된다. 두개의 Interger 객체가 3 이라는정수값을가지고있지만두개의객체는서로다른메모리번지를가지고있다. 그래서 Object 에서정의된 equals() 에의하면 flase 가되어야한다. 하지만 Integer 에서는 equals() 함수를오버라이딩했다. Object 의 equals() 는두개 [Pro-java.com] - 2 -
의객체참조값 ( 메모리번지 ) 를비교하지만이것을오버라이딩한 Interger() 함수에서는그포함한값을비교해서같은 true 를리턴하도록오버라이딩한것이다. 객체의 equals() 메소드를사용할때는 equals() 가오버라이딩됐는지를확인하고사용해야한다. 객체.equals(null) 은항상 false 가리턴된다. 2) protected void finalize() 가비지컬렉터가이객체를가비지컬렉션할후보라고생각할때 ( 이객체를참조하는값이하나도없을때 ) 호출된다. 즉, 가비지컬렉션되기전에호출되는메소드이다. 객체에관한마지막정리작업 ( 비메모리자원의반환등 ) 을하는용도로주로쓰인다. 3) Class getclass() 해당객체의런타임클래스를리턴한다. [ 참고 ] 런타임클래스자바는하위클래스의객체가상위클래스의참조변수에대입될수있다. 그러므로객체참조변수의실제적인형은실행시간이되어봐야알수있다. 아래의예를보자. Object obj = new Object(); //1 System.out.println(obj.getClass()); //2 Integer i = new Integer(7); obj = i; //3 System.out.println(obj.getClass()); //4 System.out.print(obj.equals(new Integer(7))); //5 결과는다음과같다. class java.lang.object class java.lang.integer //1 에서 obj 객체가 Object 형으로선언된다. 그러므로 //2 의 getclass() 메소드에의해 "class java.lang.object" 라는값이출력이된다. //3 에서는 Object 로선언된동일한변수에 Integer 객체가대입된다. obj 가실제참조하고있는 ( 가리키고있는 ) 변수는 Integer 형의객체를가리키게된다. 즉런타임클래스는 Integer 클래스가된다. //5 에서 obj.equals() 를하면 Object 의 equals() 메소드가호출되지않고 Integer 의 equals() 메소드가호출된다. 즉, 메소드는런타임클래스의메소드가호출되고변수는선언형의멤버변수가참조된다. 4) String tostring() 객체가표현하는내용을 String 으로리턴한다. Object 의 tostring() 은단순히클래스이름과해쉬코드값을출력하도록아래와같이정의되어있다. getclass().getname() + '@' + Integer.toHexString(hashCode()) 이메소드도 equals() 메소드처럼그클래스가포함하는내용을출력하도록오버라이딩되어있는곳이있다. [Pro-java.com] - 3 -
Integer i = new Integer(9); System.out.print(i.toString()); //Integer i 의정수값이 String 으로변형되어출력된다. 5) 기타메소드 protected Object clone() 이객체의값을가지고있는동일한타입의객체를만들어리턴한다. int hashcode() 객체의 hash code 값을리턴한다. void notify() 이객체가가지고있는락을기다리는쓰레드중하나를깨운다. void notifyall() 이객체가가지고있는락을기다리는모둔쓰레드를깨운다. void wait() 다른쓰레드가이객체에해당하는 notify() 나 notifyall() 을호출할때까지현재의쓰레드를멈춘다. void wait(long timeout) 다른쓰레드가이객체에해당하는 notify() 나 notifyall() 을호출하거나 timeout 만큼의시간이지날때까지현재의쓰레드를멈춘다. void wait(long timeout, int nanos) 다른쓰레드가이객체에해당하는 notify() 나 notifyall() 을호출하거나 timeout 만큼의시간이지날때까지현재의쓰레드를멈춘다. 이메소드는 void wait(long timeout) 와비슷하지만더세밀한부분까지시간을조절할수있다. 타임아웃시간은 1000000*millis+nanos 로된다. 2. Math class 기본적산술관계된메소드들과상수 E 와 PI 를포함한다. 모든메소드와멤버변수가 static 으로선언되어 Math 클래스객체를생성하지않고사용가능하다. 2.1 math 함수 1(abs, ceil, floor, max, min, random, round) static int abs(int a); double, float, int long 형을파라미터로받는 4 개의메소드가존재한다. 절대값을리턴한다. static double ceil(double a) a 보다크거가같은정수중에가장작은정수값을리턴한다. [Pro-java.com] - 4 -
static double floor(double a) a 보다작거가같은정수중에가장큰정수값을리턴한다. max 는아래와같은 4 가지타입이존재하며그기능은두수중큰값을리턴한다. 둘중하나가 NaN 이면 NaN 을리턴한다. 음의 0 과양의 0 이아규먼트로오면양의 0 이리턴된다. static double max(double a, double b) static float max(float a, float b) static int max(int a, int b) static long max(long a, long b) min 은아래와같은 4 가지타입이존재하며그기능은두수중작은값을리턴한다. 둘중하나가 NaN 이면 NaN 을리턴한다. 음의 0 과양의 0 이아규먼트로오면음의 0 이리턴된다. static double min(double a, double b) static float min(float a, float b) static int min(int a, int b) static long min(long a, long b) public static double random() 0.0 보다크거나같고 1.0 보다작은임의의 double 숫자를리턴한다. static long round(double a) 소수첫자리에서반올림된 long 값을리턴한다. (long)math.floor(a + 0.5d) 와같은기능을한다. static int round(float a) 소수첫자리에서반올림된 int 값을리턴한다. (int)math.floor(a + 0.5f) 와같은기능을한다. 2.2 Math 함수 2(sin cos, tan, sqrt.) public static double sin(double a) a 를라디안값으로하는사인값을리턴한다. public static double cos(double a) a 를라디안값으로하는코사인값을리턴한다. public static double tan(double a) a 를라디안값으로하는탄젠트값을리턴한다. public static double sqrt(double a) a 의제곱근값을리턴한다. [Pro-java.com] - 5 -
3. String 객체의불변성 (String 과 StringBuffer) String 클래스는원칙적으로변하지않는읽기전용의문자열을저장하기위한클래스이다. StringBuffer 클래스는수정할수있는문자열을표현하기위한클래스이다. StringBuffer 클래스는문자열수정을위한여러메소드를제공한지만 String 클래스는그러한메소드들을제공하지않는다. 3.1 String 객체의불변성 다음의두가지경우를보자. String str = new String("pro-"); //1 str += "java"; //2 System.out.println(str); StringBuffer sb = new StringBuffer("pro-"); sb.append("java"); System.out.println(sb); 첫번째예에서는 String 클래스를선언하고 += 연산을이용해두스트링을더했다. 두번재예에서는 StringBuffer 클래스를선언하고메소드 append() 를사용해스트링을더했다. 둘다우리가원하는결과인 pro-java 를출력한다. 왠뻥인가! 분명히 String 클래스는읽기전용의변하지않는문자열을저장하기위한클래스라고했는데, 위의코드를보니 + 기호하나로스트링의덧셈이너무쉽게된다. 하지만그내부를들여다보자. //1 에서스트링클래스가생성된다. //2 에서는생성된스트링클래스에 java 를더할수없다. 그래서 pro- 라는문자값을가진 StringBuffer 를임시로만든다. 그런후임시로만들어진 StringBuffer 객체의 append 메소드를 java 파라미터로호출한다. 그런다음결과를다시 String 객체로변환후 str 에대입한다. 두번째예에서는이러한임시변수의생성없이 StringBuffer 클래스의메소드를이용해바로스트링의연결이이루어진다. String 과 StringBuffer 의연산은수백배의수행속도차이까지보인다. 사용에각별한주의를해야한다. 3.2 파라미터로사용되는경우 String 과 StringBuffer 객체는파라미터로사용되는경우도다른결과를보인다. 이것은자바의값에의한전달의효과이다. 아래의두가지경우를보자. String addgood(string str){ String good = new String( good ); return str += good; //1 [Pro-java.com] - 6 -
} StringBuffer addgood(stringbuffer sb){ StringBuffer good = new StringBuffer( good ); return sb.append(good); //2 } String strorigin = new String( java is ); StringBuffer sborignin = new StringBuffer( java is ); addgood(strorgin); //3 addgood(sborigin); //4 System.out.println( strorigin : + strorigin); //5 System.out.println( sborigin : + sborigin); //6 위의두가지경우모두전달받은문자열에 good 이라는문자열을덧붙여리턴한다. 하지만첫번째인경우 //3 에서매개변수로전달된 strorign 은원래의값이수정되지않고, //4 에서전달된 sborigin 은원래의값이변경된다. 즉, //5 에서는 java is 가출력되고 //6 에서는 java is good 이출력된다. 이러한현상은 String 과 StringBuffer 객체의특성과자바의파라미터전달방법인값에의한전달 (call by value) 때문에일어나는현상이다. 위에서 String 파라미터는원래의값이변형되지않았으니값이복사되어전달되었고 StringBuffer 파라미터는원래의값이변형되었으니참조에의해전달되었을까? 아니다자바는항상값에의한전달을한다. 객체를가리키는참조변수는그객체가저장된메모리상의주소를가지고있다. strorigin 과 sborigin 모두그객체의저장된주소를가지고있다. 이두개의값이파라미터로전달되면이변수의값 ( 메모리주소 ) 이복사되어전달된다. 그새로운변수들이 str 과 sb 이다. //1 에서 str 에새로운값 (str + good) 을저장한 String 클래스의주소가저장된다. str 이라는지역변수의값이바뀐것이다. 원래의 String 변수인 strorigin 은변형되지않았다. 값에의한전달이기때문이다. 그럼두번째 StringBuffer 의경우는왜값이변형되었을까? //2 에서지역변수 sb 는멤버메소드를사용해 good 라는값을추가한다. sb 와 sborigin 은다른변수이나동일한값 ( 동일한주소값 ) 을가지고있다. 즉, 동일한 StringBuffer 객체를가리키고있다. 그래서, sb 변수를이용해값을바꾸더라도원래의값이바뀌게된다. 이러한현상은 String 클래스는불변성, 읽기전용을위한클래스이기때문에값을수정하는메소드가없고, StringBuffer 는값을수정하는메소드가있기때문에, 그리고자바는값에의한전달을하기때문이다. [Pro-java.com] - 7 -
104 strorigin str //1 실행전 strorigin 과 str 은같은값을가지고있다. 즉 104 라는번지값을가지고있다. [1 실행전 ] 104 strorigin 116 str //1 실행후 strorigin 은이전의객체주소 (102) 를가지고있고 str 은새로생성된객체주소 (116) 을가지고있다. 지역변수 str 에새로운스트링이대입됐기때문이다. [1 실행후 ] [Pro-java.com] - 8 -
126 sborigin sb //2 실행전 sborigin 과 sb 은같은값을가지고있다. 즉 126 이라는번지값을가지고있다. [2 실행전 ] 126 sborigin sb //2 실행후 sborigin 과 sb 은같은값을가지고있다. 동일한객체의멤버메소드를사용해스트링을추가했기때문에동일한주소값을가진다. [2 실행후 ] [Pro-java.com] - 9 -