[포스코DX|Java|1주] 5일차 수업
포스코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
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해야, 동일성 비교가 가능하다.
* **/
}
}
오버라이드 이후,
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문
String의 동일성 비교와 동질성 비교
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의 불변성
==
"!".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);
}
}
시간 뽑아 내기
- 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);
}
}
- Calendar
(+) 팩토리 메소드와 싱글톤