Chap 11. 기본 클래스 [Do it! 자바 프로그래밍 입문]

doriskim·2022년 12월 16일
0

*본 내용은 [Do it! 자바 프로그래밍 입문] 책과 강의를 보고 공부하면서 요점 정리한 내용입니다.

◼ java.lang 패키지

  • 프로그래밍시 import하지 않아도 자동으로 import 됨
  • import java.lang.*; 문장이 추가됨
  • 많이 사용하는 기본 클래스들이 속한 패키지
  • String, Integer, System 등

◼ Object 클래스

✔ Object 클래스

  • 모든 클래스의 최상위 클래스
  • java.lang.Object 클래스
  • 모든 클래스는 Object 클래스에서 상속 받음
  • 모든 클래스는 Object 클래스의 메서드를 사용할 수 있음
  • 모든 클래스는 Object 클래스의 메서드 중 일부는 재정의 할 수 있음
    (final로 선언된 메서드는 재정의 할 수 없음)
  • 모든 클래스는 Object 타입으로 형 변환 가능하다.
  • 컴파일러가 extends Object를 자동으로 추가함

✔ Object 클래스 메서드

메서드설명
String toString()객체를 문자열로 표현하여 반환합니다. 재정의하여 객체에 대한 설명이나 특정 멤버 변수 값을 반환합니다.
boolean equals(Object obj)두 인스턴스가 동일한지 여부를 반환합니다. 재정의하여 논리적으로 동일한 인스턴스임을 정의할 수 있습니다.
int hashCode()객체의 해시 코드 값을 반환합니다.
Object clone()객체를 복제하여 동일한 멤버 변수 값을 가진 새로운 인스턴스를 생성합니다.
Class getClass()객체의 Class 클래스를 반환합니다. (final로 선언됨)
void finalize()인스턴스가 힙 메모리에서 제거될 때 가비지 컬렉터(GC)에 의해 호출되는 메서드입니다. 네트워크 연결 해제, 열려 있는 파일 스트링 해제 등을 구현합니다. (final로 선언됨)
void wait()멀티스레드 프로그램에서 사용하는 메서드입니다. 스레드를 '기다리는 상태(non runnable)로 만듭니다. (final로 선언됨)
void notify()wait()메서드에 의해 기다리고 있는 스레드(non runnable 상태)를 실행 가능한 상태(runnable)로 가져옵니다. (final로 선언됨)

✔ toString() 메서드

  • Object 클래스의 메서드
getClass().getName() + '@' + Integer.toHexString(hashCode())

클래스이름 @ 해시코드값

Object.Book@16f65612
  • 객체의 정보를 String으로 바꾸어서 사용할 때 많이 쓰임
  • String이나 Integer 클래스에는 이미 재정의 되어 있음
    ∙ String은 문자열 반환
    ∙ Integer는 정수값 반환

ToStringEx.java

package object;

class Book{
	String title;
	String author;
	
	Book(String title, String author){
		this.title = title;
		this.author = author;
	}

	@Override //toString 재정의하기
	
	public String toString() {
		return title + "," + author;
	}
	
}

public class ToStringEx {

	public static void main(String[] args) {

		Book book = new Book("두잇자바", "은종님");
		System.out.println(book);
		
		String str = new String("test");
		System.out.println(str);
	}

}

재정의 하기 전 실행 결과

object.Book@1d81eb93
test

재정의 한 뒤 실행 결과

두잇자바,은종님
test

✔ equals() 메서드

  • 두 인스턴스의 주소 값을 비교하여 true/false를 반환
  • 재정의하여 두 인스턴스가 논리적으로 동일함의 여부를 반환
  • 같은 학번의 학생인 경우 여러 인스턴스의 주소값은 다르지만, 같은 학생으로 처리해야 학점이나 정보산출에 문제가 생기지 않으므로 이런 경우 equals() 메서드를 재정의 함
  • String이나 Integer 클래스에는 이미 재정의 되어 있음(물리적으로 다르지만 논리적으로 같게)
    ∙ String은 같은 문자열의 경우 true를 반환
    ∙ Integer는 정수 값이 같은 경우 true를 반환

EqualsTest.java

package object;

class Student{
	int studentID;
	String studentName;
	
	Student(int studentID, String studentName){
		this.studentID = studentID;
		this.studentName = studentName;
	}

	@Override // equals 재정의하기
	public boolean equals(Object obj) {
		if(obj instanceof Student) {
			Student std = (Student)obj;
			if(studentID == std.studentID) 
				return true;
			else
				return false;
		}
		return false;
	}

}

public class EqualsTest {
	
	public static void main(String[] args) {
		String str1 = new String("test");
		String str2 = new String("test");
	
		System.out.println(str1 == str2); // 인스턴스의 힙 메모리 주소가 각각 다르므로
		System.out.println(str1.equals(str2)); // String에서 재정의 됨. 문자열이 같은지 확인
		
		Student std1 = new Student(10001, "Tomas");
		Student std2 = new Student(10001, "Tomas");
		
		System.out.println(std1 == std2);
		System.out.println(std1.equals(std2));
		
	}

}

재정의 하기 전 실행 결과

false
true
false
false

재정의 한 뒤 실행 결과

false
true
false
true

✔ hashCode() 메서드

  • hash: 정보를 저장, 검색하기 위해 사용하는 자료구조
  • 자료의 특정 값(키 값)에 대해 저장 위치를 반환해주는 해시 함수를 사용함
저장위치 = 해시함수 객체정보
index = hash(key)
  • 해시 함수는 어떤 정보인가에 따라 다르게 구현됨
  • hashCode()메서드는 인스턴스의 저장 주소를 반환함
  • 힙 메모리에 인스턴스가 저장되는 방식이 hash
  • hashCode()의 반환 값: 자바 가상 머신이 저장한 인스턴스의 주소값을 10진수로 나타냄
  • 서로 다른 메모리의 두 인스턴스가 같다면??
    ∙ 재정의된 equals()메서드의 값이 true
    ∙ 동일한 hashCode() 반환 값을 가져야 함
  • 논리적으로 동일함을 위해 equals()메서드를 재정의 하였다면 hashCode()메서드로 재정의하여 동일한 값이 반환되도록 함
  • String 클래스: 동일한 문자열 인스턴스에 대해 동일한 정수가 반환됨
  • Integer 클래스: 동일한 정수값의 인스턴스에 대해 같은 정수값이 반환

EqualsTest.java

package object;

class Student{
	int studentID;
	String studentName;
	
	Student(int studentID, String studentName){
		this.studentID = studentID;
		this.studentName = studentName;
	}

	@Override // equals 재정의하기
	public boolean equals(Object obj) {
		if(obj instanceof Student) {
			Student std = (Student)obj;
			if(studentID == std.studentID) 
				return true;
			else
				return false;
		}
		return false;
	}
	
	// hashCode 재정의하기
	public int hashCode() {
		return studentID; // 주로 equals를 재정의할 때 쓰인 멤버 변수를 가져다 사용
	}

}

public class EqualsTest {
	
	public static void main(String[] args) {
		String str1 = new String("test");
		String str2 = new String("test");
	
		Student std1 = new Student(10001, "Tomas");
		Student std2 = new Student(10001, "Tomas");

		//String 인스턴스 hashCode()함수 호출-->같은 값 출력됨
		System.out.println(str1.hashCode());
		System.out.println(str2.hashCode());

		//String 인스턴스 해시코드 값 출력하기
		System.out.println(System.identityHashCode(str1));
		System.out.println(System.identityHashCode(str2));
		
        //Student 인스턴스 hashCode()함수 호출-->다른 해시코드 값 출력됨
		System.out.println(std1.hashCode());
		System.out.println(std2.hashCode());
        
        //identityHashCode()는 해시코드 값 return하는 함수이다.
		System.out.println(System.identityHashCode(std2)); 
		
		
	}

}

재정의 하기 전 실행 결과

3556498 //String 인스턴스 hashCode()함수 호출
3556498
495053715 //String 인스턴스 해시코드 값 출력하기
1922154895
883049899 //Student 인스턴스 hashCode()함수 호출
2093176254
2093176254

재정의 한 뒤 실행 결과

3556498
3556498
495053715
1922154895
10001 //Student 인스턴스 hashCode()함수 호출-->재정의로 같은 값 출력됨
10001
883049899

✔ clone() 메서드

  • 객체의 원본 복제하는데 사용하는 메서드
  • 원본을 유지해놓고 복사본을 사용할 때
  • 기본 틀(prototype)을 두고 복잡한 생성과정을 반복하지 않고 복제
  • clone()메서드를 사용하면 객체의 정보(멤버변수 값)가 같은 인스턴스가 또 생성되는 것이므로 객체 지향 프로그램의 정보 은닉, 객체 보호의 관점에서 위배될 수 있음
  • 객체의 clone() 메서드 사용을 허용한다는 의미로 cloneable 인터페이스를 명시해 줌
    implements Cloneable 작성해주지 않으면 오류 발생

ObjectCloneTest.java

package object;

class Point{
	int x;
	int y;
	
	Point(int x, int y){
		this.x = x;
		this.y = y;
	}
	
	public String toString() {
		return "x=" + x + "," + "y=" + y;
	}
}

class Circle implements Cloneable{ // implements Cloneable 써주지 않으면 오류 발생
	Point point;
	private int radius;
	
	public Circle(int x, int y, int radius) {
		point = new Point(x, y);
		this.radius = radius;
	}
	public String toString() {
		return "원점은 " + this.point + "이고, 반지름은 " + radius + "입니다.";
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}

public class ObjectCloneTest {

	public static void main(String[] args) throws CloneNotSupportedException { 
    // 클론할 때 클론할 수 없을 때의 예외처리
		
		Circle circle = new Circle(10, 20, 5);
		Circle cloneCircle = (Circle)circle.clone();
		
		System.out.println(System.identityHashCode(circle));
		System.out.println(System.identityHashCode(cloneCircle));
		
		System.out.println(circle);
		System.out.println(cloneCircle);
	}

}

실행 결과

1922154895
883049899
원점은 x=10,y=20이고, 반지름은 5입니다.
원점은 x=10,y=20이고, 반지름은 5입니다.

서로 다른 해시코드 값 가진 인스턴스 만들어짐

◼ String 클래스

✔ String 클래스

  • String을 선언하는 두 가지 방법
String str1 = new String("abc"); 	// 생성자의 매개변수로 문자열 생성
String str2 = "test";				// 문자열 상수를 가리키는 방식

(어딘가에 있는 "test"의 주소를 가리키게 됨)

  • 힙 메모리에 인스턴스로 생성되는 경우와 상수 풀(constant pool)에 있는 주소를 참조하는 방법 두 가지
    (상수 풀의 문자열을 참조하면 모든 문자열이 같은 주소를 가리킴)

StringTest.java

package string;

public class StringTest {

	public static void main(String[] args) {

		String str1 = new String("abc");
		String str2 = new String("abc");
		System.out.println(str1 == str2);
		
		String str3 = "abc";
		String str4 = "abc";
		System.out.println(str3 == str4);
	}

}

실행 결과

false
true

✔ String 클래스로 문자열 연결

  • 한 번 생성된 String 값(문자열)은 불변(immutable). final로 선언되어 선언된 이후에 변하지 않는다.
  • 두 개의 문자열을 연결하면 새로운 인스턴스가 생성됨
  • 문자열 연결을 계속하면 메모리에 gabage가 많이 생길 수 있음-->어떻게 해야할까?

StringTest.java

package string;

public class StringTest {

	public static void main(String[] args) {

		String str1 = new String("java");
		String str2 = new String("android");

		System.out.println(System.identityHashCode(str1));
		
		str1 = str1.concat(str2);
   		//str1에 str2가 붙은게 아니라 javaandroid 연결된 새로운 메모리가 생성되어 그 문자열을 가리키게 됨

		System.out.println(str1);
		System.out.println(System.identityHashCode(str1));
	}

}

실행 결과

1313922862
javaandroid
495053715 // 다른 메모리값 출력된다.

✔ StringBuilder, StringBuffer 클래스 사용하기

  • 내부적으로 가변적인 char[] 배열을 가지고 있는 클래스
  • 문자열을 여러 번 연결하거나 변경할 때 사용하면 유용함
  • 매번 새로 생성하지 않고 기존 배열을 변경하므로 gabage가 생기지 않음
  • StringBuffer는 멀티스레드 프로그래밍에서 동기화(sybchronization)을 보장하지만 StringBuilder는 동기화를 지원하지 않음
  • 단일 쓰레드 프로그램에서는 StringBuilder를 사용하기를 권장
  • toString() 메서드로 String 클래스로 반환할 수 있다.
  • String을 사용하다가 StringBuilder가 필요한 상황이 생기면 사용했다가 다시 String 클래스로 반환하자

StringBuilderTest.java

package string;

public class StringBuilderTest {

	public static void main(String[] args) {

		String str1 = new String("java");
		System.out.println(System.identityHashCode(str1));
		
		StringBuilder buffer = new StringBuilder(str1);
		System.out.println(System.identityHashCode(buffer));
	
		buffer.append(" and");
		buffer.append(" android");
		System.out.println(System.identityHashCode(buffer));
		
		String str2 = buffer.toString();
		System.out.println(str2);

	}

}

실행 결과

1313922862
495053715
495053715 //같은 값
java and android

◼ Wrapper 클래스

✔ Wrapper 클래스

  • 기본 자료형(primitive data type)에 대한 클래스
기본형Wrapper 클래스
booleanBoolean
byteByte
charCharacter
shortShort
intInteger
longLong
floatFloat
doubleDouble

✔ 오토 박싱(autoboxing)과 언박싱(unboxing)

  • Integer는 객체이고, int는 4바이트 기본 자료형임

  • 두 개의 자료를 같이 연산할 때 자동으로 변환이 일어남

  • 자바5.0 이전엔 Integer와 int를 더할 수 없었음. 5.0 이후엔 자동으로 컴파일러가 해줌

Integer num1 = new Integer(100);
int num2 = 200;
int sum = num + num2; // num이 num.intValue()로 변환(언박싱)
Integer num3 = num2; // num2가 integer.valueOf(num2)로 변환(오토박싱)

Integer i = new Integer(100); // 이 생성자 9.0 이후부터 자바에서 쓰지 않을 예정이므로
Integer i = 100; // 다음과 같이 사용을 권장

◼ Class 클래스

✔ Class 클래스

  • 자바의 모든 클래스와 인터페이스는 컴파일 후 class 파일로 생성됨
  • class 파일에는 객체의 정보(멤버변수, 메서드, 생성자 등)가 포함되어 있음
  • Class 클래스는 컴파일된 class 파일에서 객체의 정보를 가져올 수 있음

✔ Class 클래스 사용하기

1. Object 클래스의 getClass()메서드 사용하기
이미 인스턴스가 있는 경우.
getClass()는 Class 클래스를 반환해준다.

String s = new String();
Class c = s.getClass(); // getClass()메서드의 반환형은 Class

2. 클래스 파일 이름을 Class 변수에 직접 대입하기

Class c = String.Class;

3. Class.forName("클래스 이름")메서드 사용하기
클래스 이름을 String으로 가져와서 클래스를 메모리에 올리는 메서드(동적로딩)
1,2 방법의 경우 해당 클래스가 컴파일되어있어야 사용 가능(static로딩). 하지만 forName 사용하는 경우 해당 이름을 가진 클래스가 있으면 메모리에 로딩시킨다(동적로딩).
자주 사용하는 방법이니 알아두자.

Class c = Class.forName("java.lang.String");

✔ Class 클래스로 정보 가져오기

  • reflection 프로그래밍
    로컬에서 없는 클래스를 가져다 사용하는 것
    Class 클래스를 이용하여 클래스의 정보(생성자, 멤버변수, 메서드)를 가져오고 이를 활용하여 인스턴스를 생성하고, 메서드를 호출하는 등의 프로그래밍 방식
  • 로컬 메모리에 객체가 없어서 객체의 데이터 타입을 직접 알 수 없는 경우(원격에 객체가 있는 경우 등) 객체 정보만을 이용하여 프로그래밍 할 수 있음
  • Constructor, Method, Filed 등 java.lang.reflect 패키지에 있는 클래스들을 활용하여 프로그래밍
  • 일반적으로 자료형을 알 수 있는 경우에는 사용하지 않음

✔ Class.forName() 메서드로 동적 로딩하기

  • 동적 로딩이란?
    컴파일시에 데이터 타입이 모두 binding되어 자료형이 로딩되는 것(static loading)이 아니라 실행중에 데이터 타입을 알고 binding되는 방식
  • 프로그래밍 할 때는 어떤 클래스를 사용할지 모를 때 변수로 처리하고 실행될 때 해당 변수에 대입된 값의 클래스가 실행될 수 있도록 Class 클래스에서 제공하는 static 메서드
  • 실행시에 로딩되므로 경우에 따라 다른 클래스가 사용될 수 있어 유용함
  • 컴파일 타임에 체크할 수 없으므로 해당 문자열에 대한 클래스가 없는 경우 예외(ClassNotFoundException)이 발생할 수 있음

[예제1]
Person.java

package classex;

public class Person {

	String name;
	int age;
	
	public Person() {}
	
	public Person(String name) {
		this.name = name;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
}

ClassTest.java

package classex;

public class ClassTest {
	
	public static void main(String[] args) throws ClassNotFoundException {


		Person person = new Person();
		
		Class pClass1 = person.getClass(); // getClass()는 Object의 메서드이다.
		System.out.println(pClass1.getName()); // getName이 Person클래스의 이름 가져옴
		
		Class pClass2 = Person.class;
		System.out.println(pClass2.getName());
		
		Class pClass3 = Class.forName("classex.Person"); // 없는 클래스를 찾는 상황을 대비해 에러 처리 해준다.
		System.out.println(pClass3.getName());
		

		
	}

}

실행 결과

classex.Person
classex.Person
classex.Person

[예제2]
StringTest.java

package classex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class StringTest {

	public static void main(String[] args) throws ClassNotFoundException {

		Class strClass = Class.forName("java.lang.String");
		
		Constructor[] cons = strClass.getConstructors();
		for(Constructor c : cons) {
			System.out.println(c); // String 클래스의 Constructor 정보들을 알 수 있다.
		}

		System.out.println("======================");
		
		Field[] fields = strClass.getFields();
		for(Field f : fields) {
			System.out.println(f);
		}
		
		System.out.println("======================");
		
		Method[] methods = strClass.getMethods();
		for(Method m : methods) {
			System.out.println(m);
		}
		
	}

}

실행 결과

public java.lang.String(java.lang.StringBuffer)
public java.lang.String(java.lang.StringBuilder)
public java.lang.String(byte[],int,int,java.nio.charset.Charset)
public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],java.nio.charset.Charset)
public java.lang.String(byte[],int,int)
public java.lang.String(byte[])
public java.lang.String(char[],int,int)
public java.lang.String(char[])
public java.lang.String(java.lang.String)
public java.lang.String()
public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int)
public java.lang.String(byte[],int,int,int)
public java.lang.String(int[],int,int)
===============
public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER
===============
public boolean java.lang.String.equals(java.lang.Object)
public int java.lang.String.length()
public java.lang.String java.lang.String.toString()
public int java.lang.String.hashCode()
public void java.lang.String.getChars(int,int,char[],int)
public int java.lang.String.compareTo(java.lang.String)
public int java.lang.String.compareTo(java.lang.Object)
public int java.lang.String.indexOf(int)
public int java.lang.String.indexOf(java.lang.String)
public int java.lang.String.indexOf(java.lang.String,int)
public int java.lang.String.indexOf(int,int)
public static java.lang.String java.lang.String.valueOf(int)
public static java.lang.String java.lang.String.valueOf(char[])
public static java.lang.String java.lang.String.valueOf(java.lang.Object)
public static java.lang.String java.lang.String.valueOf(boolean)
public static java.lang.String java.lang.String.valueOf(char[],int,int)
public static java.lang.String java.lang.String.valueOf(char)
public static java.lang.String java.lang.String.valueOf(double)
public static java.lang.String java.lang.String.valueOf(float)
public static java.lang.String java.lang.String.valueOf(long)
public char java.lang.String.charAt(int)
public int java.lang.String.codePointAt(int)
public int java.lang.String.codePointBefore(int)
public int java.lang.String.codePointCount(int,int)
public int java.lang.String.offsetByCodePoints(int,int)
public byte[] java.lang.String.getBytes(java.nio.charset.Charset)
public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException
public void java.lang.String.getBytes(int,int,byte[],int)
public byte[] java.lang.String.getBytes()
public boolean java.lang.String.contentEquals(java.lang.CharSequence)
public boolean java.lang.String.contentEquals(java.lang.StringBuffer)
public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int)
public boolean java.lang.String.regionMatches(int,java.lang.String,int,int)
public boolean java.lang.String.startsWith(java.lang.String,int)
public boolean java.lang.String.startsWith(java.lang.String)
public int java.lang.String.lastIndexOf(java.lang.String)
public int java.lang.String.lastIndexOf(java.lang.String,int)
public int java.lang.String.lastIndexOf(int,int)
public int java.lang.String.lastIndexOf(int)
public java.lang.String java.lang.String.substring(int,int)
public java.lang.String java.lang.String.substring(int)
public boolean java.lang.String.isEmpty()
public java.lang.String java.lang.String.replace(char,char)
public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence)
public boolean java.lang.String.matches(java.lang.String)
public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
public java.lang.String[] java.lang.String.split(java.lang.String)
public java.lang.String[] java.lang.String.split(java.lang.String,int)
public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.CharSequence[])
public static java.lang.String java.lang.String.join(java.lang.CharSequence,java.lang.Iterable)
public java.lang.String java.lang.String.toLowerCase()
public java.lang.String java.lang.String.toLowerCase(java.util.Locale)
public java.lang.String java.lang.String.toUpperCase()
public java.lang.String java.lang.String.toUpperCase(java.util.Locale)
public java.lang.String java.lang.String.trim()
public java.lang.String java.lang.String.strip()
public java.lang.String java.lang.String.stripLeading()
public java.lang.String java.lang.String.stripTrailing()
public java.util.stream.Stream java.lang.String.lines()
public java.lang.String java.lang.String.repeat(int)
public boolean java.lang.String.isBlank()
public char[] java.lang.String.toCharArray()
public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[])
public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[])
public java.lang.Object java.lang.String.resolveConstantDesc(java.lang.invoke.MethodHandles$Lookup) throws java.lang.ReflectiveOperationException
public java.lang.String java.lang.String.resolveConstantDesc(java.lang.invoke.MethodHandles$Lookup)
public java.util.stream.IntStream java.lang.String.codePoints()
public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
public int java.lang.String.compareToIgnoreCase(java.lang.String)
public boolean java.lang.String.endsWith(java.lang.String)
public java.lang.CharSequence java.lang.String.subSequence(int,int)
public java.lang.String java.lang.String.concat(java.lang.String)
public boolean java.lang.String.contains(java.lang.CharSequence)
public java.lang.String java.lang.String.indent(int)
public java.lang.String java.lang.String.stripIndent()
public java.lang.String java.lang.String.translateEscapes()
public java.util.stream.IntStream java.lang.String.chars()
public java.lang.Object java.lang.String.transform(java.util.function.Function)
public java.lang.String java.lang.String.formatted(java.lang.Object[])
public static java.lang.String java.lang.String.copyValueOf(char[],int,int)
public static java.lang.String java.lang.String.copyValueOf(char[])
public native java.lang.String java.lang.String.intern()
public java.util.Optional java.lang.String.describeConstable()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

0개의 댓글

관련 채용 정보