포스코DX X 비트교육센터 6기 - 자바API


예외 처리

package exception;

import java.io.IOException;

public class MyClass {
	public void danger() throws IOException, MyException {
		System.out.println("some code1.....");
		System.out.println("some code2.....");

		if( 3 -3 == 0) {
			throw new MyException();
		}
		
		if (1 - 1 == 0) {
			throw new IOException(); // 내가 메소드를 구현했는데, throw하나 있으면 상단에 throws 있어야함.
		}

		System.out.println("some code3....."); // exception으로 여기 밑에 안와서 오류가 남. 그럼 상단을 if처리하면 됨.
		System.out.println("some code4.....");

	}
}

package exception;

import java.io.IOException;

public class MyClassTest {
	public static void main(String[] args) {
		try {
			MyClass myClass = new MyClass();
			myClass.danger();
//		} catch (IOException e) {
//			e.printStackTrace(); //예외처리로 별로 할 게 없으면, 이 문장이라도 적어두기.
//		} catch (MyException e) {
//			e.printStackTrace();
//		}
		} catch (Exception e) { // 모든 exception을 여기서 받을게.
			e.printStackTrace();
		}
	}
}

package exception;

public class MyException extends Exception {
	
	
	public MyException(String message) {
		super(message);
	}
	
	public MyException() {
		super("MyException Occurs");
	}
}

Java API 개괄

  • java.lang.* : 자바의 core 라이브러리, 자바 언어 자체.
  • java.util.* : Collection Framework - 자료구조 들어있는 것.
  • java.io.* : 입출력 스트림 클래스를 제공.
  • java.net.* : 소켓 (언어에 속한 기술x tcp/ip를 쉽게 프로그래밍하기 위한 함수들.), 네트워크 통신과 관련된 클래스 제공.

객체의 단군할아버지, Object

image

package chapter04;

public class ObjectTest01 {
	public static void main(String[] args) {
		Point point = new Point(); 
	
//		Class myClass = point.getClass(); //reflection
		System.out.println(point.getClass()); //class 이름을 담는 getClass가 Object에 있다. point가 상속받아서 사용 가능
		System.out.println(point.hashCode()); // address x 
							// reference X
							// address 기반의 해싱값이다. String->Integer (동일성 확인 가능)
		
		System.out.println(point.toString()); //getClass() + "@" + hashcode()
		System.out.println(point);
	}
}


class chapter04.Point
1665404403
chapter04.Point@63440df3
chapter04.Point@63440df3

동일성비교와 동질성 비교

  • 동일성 비교 : 같은 주소 ==
  • 동질성 비교 : 내용 비교 .equals() -> Object의 hashCode()와 관련이 있다.
package chapter04;

public class ObjectTest02 {
	public static void main(String[] args) {
		Point p1 = new Point(10, 20);
		Point p2 = new Point(10, 20);
		Point p3 = p1;

		// == : 두 객체의 동일성
		System.out.println(p1 == p2); //false
		System.out.println(p2 == p3); //false
		System.out.println(p1 == p3); //true
		
		// equals : 두 객체의 동질성(내용비교)
		//		  : 부모 클래스 Object의 기본 구현은 동일성(==) 비교와 같다
		System.out.println(p1.equals(p2)); //false
		System.out.println(p1.equals(p3)); //true
		
		/**
		 * 왜 동질성 비굔데 false인가? 
		 * 
		 * public boolean equals(Object obj) {
        	return (this == obj);
    		}
    		기본 구현은 동일성으로 되어있고,
    		override해야, 동일성 비교가 가능하다.
		 * **/
	}
}

image

image

오버라이드 이후,

false
false
true
true
true

hashCode는 주소기반!!

=> equals를 오버라이드할 때, 해시코드까지 변형해야하는데 그 이유는 해시코드는 주소기반이기에 해시코드를 바꿔야 같은지 인지하기 때문.

@Override
	public int hashCode() {
		return Objects.hash(height, width);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Rect other = (Rect) obj;
		return height == other.height && width == other.width;
	}
equals 메서드를 오버라이드할 때 hashCode 메서드도 함께 오버라이드해야 하는 이유는
주로 해시 기반의 자료 구조에서 객체를 다룰 때 발생하는 문제를 예방하기 위해서입니다.

Java에서 hashCode 메서드는 객체의 해시 코드를 반환합니다.
해시 코드는 자료 구조에서 객체를 저장하고 검색하기 위해 사용되는 해시 테이블 등에서 중요한 역할을 합니다.
만약 equals 메서드를 오버라이드하여 두 객체가 같은 내용을 가지면 true를 반환하도록 구현하였다면,
이 두 객체의 해시 코드도 같아야 합니다. 그렇지 않으면 해시 테이블 등에서 제대로 동작하지 않을 수 있습니다.

해시 기반의 자료 구조는 객체를 저장할 때 객체의 해시 코드를 기준으로 저장 위치를 결정하고, 같은 해시 코드를 가진 객체들을 관리합니다.
이때 equals 메서드와 hashCode 메서드 간의 일관성이 필요한데,
두 객체가 equals 메서드로 같다고 판단되면 반드시 같은 해시 코드를 반환해야 합니다.
그렇지 않으면 같은 내용을 가진 객체라 할지라도 해시 테이블에서 제대로 검색되지 않을 수 있습니다.

따라서, equals 메서드를 오버라이드할 때는 반드시 hashCode 메서드도 함께 오버라이드하여 일관성을 유지해야 합니다.

foreach문

image

String의 동일성 비교와 동질성 비교

image

package chapter04;

public class ObjectTest03 {
	public static void main(String[] args) {

		// String 클래스 내부에 이미 해시코드와 equals가 오버라이드되어있다.
		String s1 = new String("Hello");
		String s2 = new String("Hello");

		System.out.println(s1 == s2); // false
		System.out.println(s1.equals(s2)); // true

		System.out.println(s1.hashCode() + " : " + s2.hashCode());
		System.out.println(System.identityHashCode(s1) + " : " + System.identityHashCode(s2)); // 주소기반의 해시코드, 동일성비교

		System.out.println("=======================");
		String s3 = "hello";
		String s4 = "hello";

		System.out.println(s3 == s4); // true 동일성 비교
		System.out.println(s3.equals(s4)); // true

		System.out.println(s3.hashCode() + " : " + s4.hashCode());
		System.out.println(System.identityHashCode(s3) + " : " + System.identityHashCode(s4)); // 주소기반의 해시코드, 동일성비교

	}
}

false
true
69609650 : 69609650
2011986105 : 439904756
=======================
true
true
99162322 : 99162322
171497379 : 171497379

개행 문자

package chapter04;

public class StringTest01 {
	public static void main(String[] args) {
		// c:\temp -> 디렉토리 표시의 표준은 /인데, 윈도우만 \으로 되고, linux에서 /이렇게 해놓으면 윈도우가 알아서 해줌.
//		System.out.println("c:\temp"); //c:	emp > \t: tab 
		System.out.println("c:\\temp"); //이스케이프 \\ -> \
		
		System.out.println("\"Hello\"");
		
		// control character
		// \t : tab
		// \r : carriage return 앞으로 당기는 것.
		// \n : newline
		// \b : bell

		char c = '\'';
		System.out.println(c);
	}
}


c:\temp
"Hello"
'

디렉토리 표시의 표준은 /인데, 윈도우만 \으로 되고, linux에서 /이렇게 해놓으면 윈도우가 알아서 해줌. Drive D:\ C:\ 빼기


		String path1 = "\\poscodx2023\\Dowork";
		String path2 = "/poscodx2023/Dowork";
  • 둘 다 가능하지만, path2 방식으로 쓰기. 표준은 /이기 때문에.

String의 불변성

image

==

"!".concat(s2).concat("@")

StringBuffer

package chapter04;

public class StringTest03 {
	public static void main(String[] args) {
//		String s1 = "Hello" + "World" + "Java" + 17;
		StringBuffer sb = new StringBuffer("Hello");
		sb.append("World");
		sb.append("Java");
		sb.append(17);
//		String.valueOf(17) ; return (String) 17
		
//		StringBuffer("Hello").append("World").append("Java")+append(17); 메소드 체인 가능
		
		String s1 = sb.toString();
		
		String s2 = new StringBuffer("Hello").append("World").append("Java").append(17).toString();

		System.out.println(s1);
		System.out.println(s2);
		
		System.out.println("==========================");
		
		String s3 = "";
		for(int i =0; i<1000000; i++) {
//			s3 += i; 쓰지말자!
//			s3 = new StringBuffer(s3).append(i).toString(); 쓰지말자!
		}
		StringBuffer sb2 = new StringBuffer("");
		for(int i =0 ; i < 1000000; i++) {
			sb.append(i);
		}
		String s4 = sb.toString(); 
		
		System.out.println(s4); //굉장히 빠름. StringBuffer는 String의 + 를 대신하여 사용
		
	}
}

String methods…


		// String method들...
		String s5 = "aBcABCabc";
		System.out.println(s5.length());
		System.out.println(s5.charAt(2));
		System.out.println(s5.indexOf("abc"));
		System.out.println(s5.indexOf("abc", 7)); //abc를 7번째부터 찾음.
		System.out.println(s5.substring(3)); //3번째~끝까지 뽑기.
		System.out.println(s5.substring(3, 5)); //3번째~n-1번째(4번째)까지 뽑기.
		System.out.println(s5.toLowerCase());
		
		String s6 = " ab  cd ";
		String s7 = "efg,hij,klm,nop,qrs";
		
		String s8 = s6.concat(s7);
		System.out.println(s8);
		
		System.out.println(s6.trim()); //양쪽의 공백을 지움.
		System.out.println(s6.replaceAll(" ","")); //모든 공백을 지움. " " -> ""
		
		String[] tokens = s7.split(",");
		for(String s : tokens) {
			System.out.println(s);
		}
		
		String[] tokens2 = s7.split(" ");
		for(String s: tokens2) {
			System.out.println(s);
		}
		
		

Wrapper 클래스

  • 기본 데이터형을 객체 형식으로 다루기 위한 클래스들

ex. Byte, Short, Integer, Long, Character, Float, Double, Boolean 클래스들…

package chapter04;

public class WrapperClassTest01 {
	public static void main(String[] args) {
		// 직접 생성하게 되면 JVM의 힙상에 객체가 존재하게 된다.
		// 리터럴을 사용하면 되면 JVM 안의 Constant Poll이 관리한다.
		Integer i = new Integer(10);
		Character c = new Character('c');
		Boolean b = new Boolean(true);
		
		// Auto Boxing 
		Integer j1 = 10;
		Integer j2 = 20;
		
		System.out.println(j1 == j2);// reference 비교 = 동일성 비교
		System.out.println(j1 < j2); // auto Unboxing
		
		// Auto Unboxing 
		int m1 = j1.intValue() + 10;
		int m2 = j1 + 10;
	}
}

package chapter04;

public class WrapperClassTest02 {
	public static void main(String[] args) {
		String s = "123456";
		int i = Integer.parseInt(s);

		// cf1 반대로
		String s1 = String.valueOf(i);

		// cf2 반대로
		String s2 = "" + i;
		
		System.out.println(s + " : " + s1 + " : " + s2);
		
		int a = Character.getNumericValue('A');
		System.out.println(a);
		
		// cf 아스키 코드값
		System.out.println((int)'A');

		// 2진수 
		String s4 = Integer.toBinaryString(15);
		System.out.println(s4);
		
		// 16진수
		String s5 = Integer.toHexString(15);
		System.out.println(s5);
		
	}
}

시간 뽑아 내기

  1. Date
package chapter04;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTest {
	public static void main(String[] args) {
		Date now = new Date();
		System.out.println(now);

		printDate01(now);
		printDate02(now);

	}

	private static void printDate02(Date d) {
		// 년도(+1900)
		int year = d.getYear();

		// 월(0~11, +1)
		int month = d.getMonth();

		// 일
		int date = d.getDate();

		// 시
		int hour = d.getHours();

		// 분
		int minutes = d.getMinutes();

		// 초
		int seconds = d.getSeconds();

		System.out.println(
				(year + 1900) + "/" + (month + 1) + "/" + date + " " + hour + ":" + minutes + ":" + seconds);
	}

	private static void printDate01(Date d) {
		// 2023-08-11 15:00:00
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
		String date = sdf.format(d);

		System.out.println(date);
	}
}

  1. Calendar

(+) 팩토리 메소드와 싱글톤