* java.lang 패키지
: 많이 사용하는 기본 클래스들이 속한 패키지 (ex) String, Integer, System)
- import java.lang.*; answkd cnrk
- 프로그래밍시 자동으로 import 됨
* Object 클래스
: (java.lang.Object) 모든 클래스의 차상위 클래스
- 모든 클래스는 Object 클래스에서 상속 받음 (extends Object 안보이지만 컴파일러가 추가함)
- 모든 클래스는 Object 클래스의 메서드 사용 가능( Object 클래스의 메서드 중 일부분 재정의 가능 / final은 불가능)
✔️ Object 클래스 메서드의 종류
- toString() 메서드
: 객체의 정보를 String으로 바꾸어서 사용할 때 쓰이는 메서드 / 인스턴스의 클래스 이름과 주소값을 보여준다.
<to String()메서드의 원형>
- Object 클래스에서는
- String, Integer 클래스에는 이미 재정의 되어 있음 => 원형이 아닌 재정의된 메서드가 호출
=> 클래스의 이름과 주소값을 반환하는 것이 아니라 String은 문자열을 Integer은 정수를 반환한다.
- equals() 메서드
: 두 인스턴스의 주소값을 비교하여 boolean 값 반환 할 때 쓰이는 메서드
- 재정의 하여 두 인스턴스가 논리적으로 동일함의 여부를 반환
ex) 같은 학번의 학생
Student studentLee = new Student(100,"이상원");
Student studentLee2 = studentLee; //주소복사
Student studentSang = new Student(100,"이상원");
=> studentLee와 studentLee2는 같은 메모리의 주소를 참조하고 있음
=> studentSang은 studentLee와 학번, 이름은 같지만 다른 메모리의 주소를 참조하고 있음
따라서 두 학생이 같다는 것을 구현하기 위해 equals()메서드를 재정의해야함
class Student{
int studentID;
@Override
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student std = (Student)obj;
if(this.studentID == std.studentID) { //학번이 같으면 true 반환
return true;
} else {return false;}
}
return false;
}
}
=> 학번이 같으면 true를 반환하도록 재정의
=> String과 Integer도 각각 문자열과 정수 값을 반환하도록 재정의되어 있다.
- hashCode() 메서드
: 인스턴스의 저장 주소 반환(10진수) => 객체 정보를 알면 그 위치를 빠르게 검색 가능
*hash : 정보를 저장, 검색하기 위해 사용하는 자료구조 / 힙메모리에 인스턴스가 저장되는 방식
*해시 함수 : 자료의 특정 값(키 값)에 대해 저장 위치 반환 -> 어떤 정보인가에 따라 다르게 구현
✔️서로 다른 메모리의 두 인스턴스가 같다면?
: 재정의 된 equals()메서드 값이 true인 경우 동일한 hashCode() 반환 값을 가져야 한다.
=> 해시코드 값 = 인스턴스 주소 값 이므로 두 인스턴스 같으면 해시코드 값도 같아야 한다.
equals()메서드를 재정의 했다면 hashCode() 메서드도 재정의 해서 동일한 값 나오도록 해야함.
- String 클래스 : 동일한 문자열 인스턴스에 대해 동일한 정수 반환
- Integer 클래스 : 동일한 정수값의 인스턴스에 대해 같은 정수값 반환
- clone() 메서드
: 객체의 원본 복제하는데 사용하는 메서드 (원본 유지, 복사본 사용할 때)
- 기본 툴(prototype)을 두고 복잡한 생성과정 반복 없이 복제
- 객체의 정보가 같은 인스턴스가 또 생성됨 => 객체 지향 프로그램의 정보은닉, 객체 보호의 관점에서 위배됨
- cloneable 인터페이스 명시 (implements Cloneable) : 객체의 clone()메서드 사용 허용
<clone()메서드>
//1. Cloneable 인터페이스 함께 선언
class Studuent implements Cloneable{
···
}
//2. 오류 예외 처리
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
<복제>
Student student = new Student();
Student studentCopy = (Student)student.clone();
=> Student형 인스턴스 생성후 복제
* String 클래스
: 문자열 사용하는 메서드
- 선언하는 방법
- 생성자의 매개변수로 문자열 생성( String a = new String("abc"); ) => 힙 메모리에 인스턴스로 생성
- 문자열 상수를 가리키는 방식( String b = "test"; ) => 상수풀에 있는 주소 참조
- 문자열 연결
- 한번 생성된 String값은 불변(immutable)
=> String 클래스 구현내용에서 char형 배열이 final로 선언되어 있어 변경할 수 없기 때문에
- concat() 메서드로 두 개의 문자열 연결 => 새로운 인스턴스 생성 => 연결 계속하면 메모리에 gabage가 많이 생성됨
✔️StringBuilder, StringBuffer 클래스
: 내부적으로 가변적인 char[] 배열을 갖는 클래스로 문자열을 연결, 변경할 때 메모리가 낭비되는 문제를 해결
=> 문자열 여러번 연결하거나 변경할 때 사용 (append()로 연결)
=> 매번 새로 생성하지 않고 기존 배열을 변경하여 gabage가 많이 생기지 않는다.
<클래스 사용 예시>
//"Java" 문자열 가진 인스턴스 생성
String javaStr = new String("Java");
//String으로 부터 StringBuilder생성
StringBuilder buffer = new StringBuilder();
//문자열 추가
buffer.append(" and");
buffer.append(" android");
//String 클래스로 반환
javaStr = buffer.toString();
System.out.println(javaStr);
//출력값
Java and android
- 멀티 쓰레드 프로그래밍 : StringBuffer는 동기화(synchronization)를 보장
- 단일 쓰레드 프로그래밍 : StringBuilder 사용 권장(실행 속도가 더 빠름)
=> 여러작업(스레드)이 동시에 문자열을 변경하려 할 때 문자열을 안전하게 변경되도록 보장하는가 안하는가의 차이
- 문자열 변경한 후 toString()메서드로 String(문자열) 반환
* Wrapper 클래스
:기본 자료형(primitive data type)에 대한 클래스 => 기본 자료형을 감싼 클래스라고도 함
매개변수가 객체거나 반환 값이 객체형인 경우 사용
//객체를 매개변수로 받는 경우
public void setValue(Integer i){}
//반환 값이 객체형인 경우
public Integer returnValue(){}
- 오토박싱(autoboxing) & 언박싱(unboxing)
- 오토박싱 : 기본형을 객체형으로 바꾸는 것
- 언박싱 : 객체형을 기본형으로 꺼내는 것
=> 두 개의 자료를 같이 연산할 때 자동으로 변환됨
* Class 클래스
: 모르는 클래스의 정보를 사용할 경우에 클래스 정보를 직접 찾아야 하는데 이때 활용됨
- 자바의 모든 클래스와 인터페이스 -> 컴파일 후 class 파일 생성
- class 파일 : 객체의 정보(멤버변수, 메서드, 생성자 등)
- Class 클래스는 컴파일된 class 파일에서 객체의 정보를 가져올 수 있음
- Class 클래스 선언하고 클래스 정보를 가져오는 방법
1. Object 클래스 - getClass()메서드
Stirng s = new String();
Class c = s.getClass(); //getClass() 메서드의 반환형은 Class
2. 클래스 파일 이름 Class 변수에 직접 대입
Class c = Stirng.class; //Stirng 클래스의 Class 객체를 변수 c에 할당하는 것
3. Class.forName("클래스 이름") 메서드 사용
Class c = Class.forName("java.lang.Stirng");
- reflection 프로그래밍
: Class 클래스를 이용해 클래스의 정보를 가져오고 이를 활용해 인스턴스를 생성하고, 메서드를 호출하는 등의 프로그래밍 방식
=> 객체의 정보만을 이용해 프로그래밍이 가능 (로컬 메모리에 객체가 없어 객체의 데이터 타입을 직접 알 수 없는 경우에 Class 클래스를 쓰지만 일반적으로 자료 형을 알 수 있는 경우에는 사용하지 않는다.)
✔️클래스 정보 확인을 위한 java.lang.reflect 패키치 클래스 메서드
- getConstructors() 메서드 : String 클래스의 모든 생성자를 가져옴
- getFields() 메서드 : 모든 멤버변수(필드) 가져오기
- getMethods() 메서드 : 모든 메서드 가져오기
✔️클래스 정보를 바탕으로 인스턴스 생성 - newInstance()
: Class 클래스 메서드로 new 키워드 없이 클래스 정보만으로 인스턴스 생성하는 메서드
(항상 Object를 반환 => 생성된 객체형으로 형변환 필요)
*생성자로 인스턴스 생성
Person person = new Person();
*Class 클래스의 newInstance()메서드로 인스턴스 생성
Class pClass = Class.forName("classex.Person"); //클래스 이름으로 정보 가져오기
Person person = (Person)pClass.newInstance(); //인스턴스 생성
=> 생성된 객체형으로 형 변환
- Class.forName() 사용해서 동적 로딩 하기
- 동적 로딩 : 컴파일 시에 데이터 타입이 모두 binding( 데이터의 타입이 고정 )되어 자료형이 로딩되는 것(static loading)이 아니라 실행 중에 데이터 타입을 알고 binding(데이터의 타입이 고정)되는 방식
- 실행시에 로딩되므로 경우에 따라 다른 클래스 사용될 수 있어 유용하다.
String className = "classez.Person"
Class pClass = Class.forName(className);
=> 변수 className에 대입되는 문자열만 바꾸면 forName의 매개변수는 그대로지만 다른 클래스를 로딩 할 수 있다.
- 컴파일 타임에 문자열에 오류가 있어도 이를 알 수 없으므로 해당 문자열에 대한 클래스가 없는 경우 => 예외(ClassNotFoundException) 발생
=> 동적 로딩 방식은 컴파일 할 때 오류를 알 수 없다. (문자열 대소문자 오류 주의)
MEMO
* System.identityHashCode() : 인스턴스의 메모리 주소
* append() : 문자열 추가
* concat() : 문자열 연결
*IntValue() : Integer 클래스 내부의 int 자료형 값을 가져옴
*valueOf() : 정적 메서드로 생성자 사용하지 않고 정수나 문자열을 바로 Integer클래스로 반환 받을 수 있음
*parseInt() : 문자열이 어떤 숫자(학번)를 나타낼 때 문자열로 전달된 경우 문자열에서 iint값 바로 가져와 반환
'개발 공부 > Java' 카테고리의 다른 글
[Java] - 내부 클래스 (0) | 2023.11.14 |
---|---|
[Java] - 컬렉션 프레임워크 (0) | 2023.11.13 |
[Java] - 인터페이스 (0) | 2023.11.08 |
[Java] - 추상 클래스 (0) | 2023.11.08 |
[Java] - 상속과 다형성02 (0) | 2023.11.07 |