가장 많이 쓰는 메소드 세 개 (반드시 Overriding 해야 함)
equals - 객체가 가진 값을 비교할 때 사용
toString - 객체가 가진 값을 문자열로 반환
hashCode - 객체의 해시코드 값 반환
자바는 기본적으로 다양한 패키지를 지원, 그중에서 가장 중요한 패키지
public class WrapperExam {
public static void main(String[] args) {
int i = 5;
Integer i2 = new Integer(5);
Integer i3 = 5; //오토박싱
int i4 = i2.intValue();
int i5 = i2; //오토언박싱
}
}
기본 타입 데이터를 객체 타입의 데이터로 자동 형변환 시켜주는 기능
Integer i3 = 5; 숫자 5는 원래 기본형이지만 자동으로 Integer형태로 변환된다.
오토박싱과 반대로 객체 타입의 데이터를 기본형 타입 데이터로 자동 형변환
int i5 = i2; Integer객체타입의 값을 기본형 int로 자동으로 변환되어 값을 할당한다.
public class WrapperExam {
public static void main(String[] args) {
int i = 5;
Integer i2 = new Integer(5);
Integer i3 = 5; //오토박싱
int i4 = i2; //오토언박싱
long i2_long = i2.longValue();
long i4_long = i4.longValue(); // 오류 발생!
}
}
아무 값도 가지고 있지 않은 StringBuffer객체를 생성
StringBuffer sb = new StringBuffer();
// 해당 스트링 버퍼에 "hello", 공백, "world"를 차례대로 추가
sb.append("hello");
sb.append(" ");
sb.append("world");
// StringBuffer에 추가된 값을 toString()메소드를 이용하여 반환
String str = sb.toString();
StringBuffer sb2 = new StringBuffer();
StringBuffer sb3 = sb2.append("hello");
if(sb2 == sb3){
System.out.println("sb2 == sb3");
}
String str2 = new StringBuffer().append("hello").append(" ").append("world").toString();
System.out.println(str2);
String클래스는 문자열을 다룰 때 사용하는 클래스
String클래스는 불변클래스이다.
String str1 = "hello world";
String str2 = str1.substring(5);
System.out.println(str1);
System.out.println(str2);
실행결과
hello world
world
substring메소드는 5번째 부터 문자열을 잘라서 새로운 문자열을 반환하는 메소드
기존의 str1은 전혀 변화 없다.
String클래스를 사용할 때 가장 문제가 발생하는 경우는 다음과 같은 코드를 사용할 때이다.
String str3 = str1 + str2;
System.out.println(str3);
문자열과 문자열을 더하게 되면 내부적으로는 다음과 같은 코드가 실행
String str4 = new StringBuffer().append(str1).append(str2).toString();
System.out.println(str4);
문자열을 반복문 안에서 더하는 것은 성능상 문제가 생길 수 있으니 반드시 피하도록 하자. 객체가 여러번 생성되기 때문이다.
-> 처음부터 StringBuffer를 사용하자.
자바의 모든 클래스와 인터페이스는 컴파일 후 class 파일이 생성됨
Class 클래스는 컴파일 된 class 파일을 로드하여 객체를 동적 로드하고, 정보를 가져오는 메서드가 제공됨
Class.forName("클래스 이름") 메서드로 클래스를 동적으로 로드 함
컴파일 시에 데이터 타입이 binding 되는 것이 아닌, 실행(runtime) 중에 데이터 타입을 binding 하는 방법
프로그래밍 시에는 문자열 변수로 처리했다가 런타임시에 원하는 클래스를 로딩하여 binding 할 수 있다는 장점
컴파일 시에 타입이 정해지지 않으므로 동적 로딩시 오류가 발생하면 프로그램의 심각한 장애가 발생가능
reflection 프로그래밍 : Class 클래스를 사용하여 클래스의 정보(생성자, 변수, 메서드)등을 알 수 있고 인스턴스를 생성하고,
메서드를 호출하는 방식의 프로그래밍
로컬 메모리에 객체 없는 경우, 원격 프로그래밍, 객체의 타입을 알 수 없는 경우에 사용
java.lang.reflect 패키지에 있는 클래스를 활용하여 프로그래밍
일반적으로 자료형을 알고 있는 경우엔 사용하지 않음
Math클래스는 이름 그대로 수학계산을 위한 클래스
코싸인, 싸인, 탄젠트, 절대값, 랜덤값을 구할 수 있는 클래스
public class MathExam {
public static void main(String[] args) {
int value1 = Math.max(5, 20);
int value2 = Math.min(5, -5);
int value3 = Math.abs(-10);
double value4 = Math.random();
double value5 = Math.sqrt(25);
}
}
java.util패키지는 유용한 클래스들을 많이 가지고 있는 패키지
java.util 패키지에서 제공되는 ArrayList
기존의 배열 선언과 사용 방식은 배열의 길이를 정하고 요소의 개수가 배열의 길이보다 커지면 배열을 재할당하고 복사해야 했음
배열의 요소를 추가하거나 삭제하면 다른 요소들의 이동에 대한 구현을 해야 함
ArrayList는 객체 배열을 좀 더 효율적으로 관리하기 위해 자바에서 제공해 주는 클래스
이미 많은 메서드들이 최적의 알고리즘으로 구현되어 있어 각 메서드의 사용 방법만 익히면 유용하게 사용할 수 있음
import java.util.ArrayList;
import ch21.Book;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<Book> library = new ArrayList<Book>();
library.add(new Book("태백산맥1", "조정래"));
library.add(new Book("태백산맥2", "조정래"));
library.add(new Book("태백산맥3", "조정래"));
library.add(new Book("태백산맥4", "조정래"));
library.add(new Book("태백산맥5", "조정래"));
for(int i =0; i<library.size(); i++) {
library.get(i).showBookInfo();
}
}
}
java.util패키지에는 자료를 다룰 수 있는 자료구조 클래스가 다수 존재한다. 자료구조 클래스들을 컬렉션 프레임워크라고 한다.
컬렉션 프레임워크에서 가장 기본이 되는 interface는 Collection인터페이스
Set자료구조는 중복을 허용하지 않는 자료구조를 표현하는 인터페이스
List자료구조는 중복은 허용하면서 순서를 기억하는 자료구조를 표현.
Map자료구조는 Key와 Value를 가지는 자료구조이다.
Box 클래스
public class Box {
private Object obj;
public void setObj(Object obj){
this.obj = obj;
}
public Object getObj(){
return obj;
}
}
BoxExam 클래스
public class BoxExam {
public static void main(String[] args) {
Box box = new Box();
box.setObj(new Object());
Object obj = box.getObj();
box.setObj("hello");
String str = (String)box.getObj();
System.out.println(str);
box.setObj(1);
int value = (int)box.getObj();
System.out.println(value);
}
}
Java5에는 Generic이라는 문법이 사용됨으로써 인스턴스를 만들때 사용하는 타입을 지정하는 문법이 추가
Generic을 이용하여 Box 클래스 수정
public class Box<E> {
private E obj;
public void setObj(E obj){
this.obj = obj;
}
public E getObj(){
return obj;
}
}
Generic을 이용하여 수정한 Box를 이용하는 BoxExam클래스
public class BoxExam {
public static void main(String[] args) {
Box<Object> box = new Box<>();
box.setObj(new Object());
Object obj = box.getObj();
Box<String> box2 = new Box<>();
box2.setObj("hello");
String str = box2.getObj();
System.out.println(str);
Box<Integer> box3 = new Box<>();
box3.setObj(1);
int value = (int)box3.getObj();
System.out.println(value);
}
}
Generic을 사용함으로써 선언할때는 가상의 타입으로 선언하고, 사용시에는 구체적인 타입을 설정함으로써 다양한 타입의 클래스를 이용하는 클래스를 만들 수 있다. Generic을 사용하는 대표적인 클래스는 컬렉션 프레임워크와 관련된 클래스이다.
상위 클래스의 필요성
T 자료형의 범위를 제한할 수 있음
상위 클래스에서 선언하거나 정의하는 메서드를 활용할 수 있음
상속을 받지 않는 경우 T는 Object로 변환되어 Object 클래스가 기본으로 제공하는 메서드만 사용가능
GenericPrinter에 material 변수의 자료형을 상속받아 구현
T에 무작위 클래스가 들어갈 수 없게 Material 클래스를 상속받은 클래스로 한정
public class GenericPrinter<T extends Material> {
private T material;
public void setMaterial(T material) {
this.material = material;
}
public T getMaterial() {
return material;
}
public String toString(){
return material.toString();
}
public void printing() {
material.doPrinting();
}
}
public class Powder extends Material{
public void doPrinting() {
System.out.println("Powder 재료로 출력합니다");
}
public String toString() {
return "재료는 Powder 입니다";
}
}
제네릭 메서드란?
public class Point<T, V> {
T x;
V y;
Point(T x, V y){
this.x = x;
this.y = y;
}
public T getX() {
return x;
}
public V getY() {
return y;
}
}
public class GenericMethod {
public static <T, V> double makeRectangle(Point<T, V> p1, Point<T, V> p2) {
double left = ((Number)p1.getX()).doubleValue();
double right =((Number)p2.getX()).doubleValue();
double top = ((Number)p1.getY()).doubleValue();
double bottom = ((Number)p2.getY()).doubleValue();
double width = right - left;
double height = bottom - top;
return width * height;
}
public static void main(String[] args) {
Point<Integer, Double> p1 = new Point<Integer, Double>(0, 0.0);
Point<Integer, Double> p2 = new Point<>(10, 10.0);
double rect = GenericMethod.<Integer, Double>makeRectangle(p1, p2);
System.out.println("두 점으로 만들어진 사각형의 넓이는 " + rect + "입니다.");
}
}