한빛미디어의 <혼자 공부하는 자바>를 요약 정리했습니다.
throws에 대한 설명으로 틀린 것은 무엇입니까?
1. 생성자나 메소드의 선언 끝 부분에 사용되어 내부에서 발생된 예외를 떠넘긴다.
2. throws 뒤에는 떠넘겨야 할 예외를 쉼표(,)로 구분해서 기술한다.
3. 모든 예외를 떠넘기기 위해 간단하게 throws Exception으로 작성할 수 있다.
4. 새로운 예외를 발생시키기 위해 사용된다.
정답: 4
-> throws는 예외를 발생시키는 것이 아니라 메소드에서 처리하지 않는 예외를 호출한 곳으로 떠넘기는 역할을 합니다.
-> 🧊 java.lang 패키지
에 정리
예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
자바에서는 예외를 클래스로 관리
NullPointerException
객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생
public class NullPointerExceptionExample {
public static void main(String[] args) {
String data = null;
System.out.println(data.toString());
}
}
ArrayIndexOutOfBoundsException
배열에서 인덱스 범위를 초과할 경우 발생
ex. 길이가 3인 int[] arr = new int[3]
배열을 선언했다면, 배열 항목을 지정하기 위해 arr[0] ~ arr[2]
를 사용 가능
-> arr[3]
을 사용하면 에러 발생
public class ArrayIndexOutOfBoundsExceptionExample {
public static void main(String[] args) {
String data1 = args[0];
String data2 = args[1];
System.out.println("args[0]: " + data1);
System.out.println("args[1]: " + data2);
}
}
NumberFormatException
문자열을 숫자로 변환하는 방법
리턴 타입 | 메소드 이름(매개 변수) | 설명 |
---|---|---|
int | Integer.parseInt(String s) | 주어진 문자열을 정수로 변환해서 리턴 |
double | Double.parseDoube(String s) | 주어진 문자열을 실수로 변환해서 리턴 |
매개값인 문자열이 숫자로 변환될 수 있다면 숫자를 리턴하지만, 숫자로 변환될 수 없는 문자가 포함되어 있다면 에러 발생
public class NumberFormatExceptionExample {
public static void main(String[] args) {
String data1 = "100";
String data2 = "a100";
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2); // NumberFormatException 발생
}
}
ClassCastException
타입 변환은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생
// 문제 없음
Animal animal = new Dog()
Dog dog = (Dog) animal;
// 에러 발생
Animal animal = new Dog();
Cat cat = (cat) animal;
에러를 발생시키지 않으려면 타입 변환 전에 변환이 가능한지 instanceof 연산자로 확인
Animal animal new dog();
if(animal instanceof Dog) {
Dog dog = (Dog) animal;
} else if(animal instanceof Cat) {
Cat cat = (Cat) animal;
}
try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어 예외가 발생할 경우 예외 처리를 할 수 있도록 해줌
try {
// 예외 발생 가능 코드
} catch(예외클래스 e) {
// 예외 처리
} finally {
// 항상 실행;
}
example: Class.forName() 메소드는 매개값으로 주어진 클래스가 존재하면 Class 객체를 리턴하지만, 존재하지 않으면 에러 발생
public class TryCatchFinallyExample {
public static void main(String[] args) {
try {
Class clazz = Class.forName("java.lang.String2");
} catch(ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니다.");
}
}
다중 catch
발생되는 예외별로 예외 처리 코드를 작성
try {
// ArrayIndexOutOfBoundsException 발생
// NumberFormatException 발생
} catch(ArrayIndexOutOfBoundsException e) {
// 예외 처리1
} catch(NumberFormatException e) {
// 예외 처리2
}
catch 순서
상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 함
try {
// ArrayIndexOutOfBoundsException 발생
// 다른 Exception 발생
} catch(ArrayIndexOutOfBoundsException e) {
// 예외 처리1
} catch(Exception e) {
// 예외 처리2
}
예외 떠넘기기
throws
키워드로 메소드를 호출한 곳으로 예외를 떠넘길 수 있음
리턴타입 메소드이름(매개변수, ...) throws 예외클래스1, 예외클래스2, ... { }
리턴타입 메소드이름(매개변수, ...) throws Exception { }
throws 키워드가 붙어 있는 메소드는 반드시 try 블록 내에서 호출되어야 하고 catch 블록에서 떠넘겨 받은 예외를 처리해야 함
public void method1() {
try {
method2();
} catch(ClassNotFoundException e) {
// 예외 처리 코드
System.out.println("클래스가 존재하지 않습니다.");
}
}
public void method2() throws ClassNotFoundException {
Class clazz = Class.forName("java.lang.String2");
}
프로그램 개발에 자주 사용되는 클래스 및 인터페이스의 모음
클래스를 선언할 때 extends 키워드로 다른 클래스를 상속하지 않더라도 암시적으로 java.lang.Object 클래스를 상속
객체 비교(equals())
public boolean equals(Object obj) { ... }
Object obj1 = new Object();
Object obj2 = new Object();
boolean result = obj1.equals(obj2); // obj1: 기준 객체, obj2: 비교 객체
boolean result = (obj1 == obj2);
equals() 메소드를 재정의할 때는, 매개값이 기준 객체와 도일한 타입의 객체인지 먼저 확인해야 함
public class Member {
public String id;
public Member(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Member) {
Memeber member = (Member) obj;
if(id.equals(member.id) {
return true;
}
}
return false;
}
}
객체 해시코드(hashCode())
객체 해시코드는 객체를 식별하는 하나의 정수값
public class KeyExample {
public static void main(String[] args) {
// Key 객체를 식별키로 사용해서 String 값을 저장하는 HashMap 객체 생성
HashMap<Key String> hashMap = new HashMap<Key, String>();
// 식별키 new Key(1)로 "홍길동"을 저장함
hashMap.put(new Key(1), "홍길동")
// 식별키 new Key(1)fh "홍길동"을 읽어옴
String value = hashMap.get(new Key(1));
System.out.println(value);
}
}
public class Key {
...
@Override
public int hashCode() {
return number;
}
}
객체 문자 정보(toString()
)
객체의 문자 정보(객체를 문자열로 표현한 값)를 리턴
클래스이름@16진수해시코드
Object obj = new Object();
System.out.println(obj.toString()); // java.lang.Object@de6ced
리턴값은 자바 애플리케이션에서는 의미가 없는 정보이므로, 오버라이딩 하여 사용
import java.util.Date;
public class ToStringExample {
public static void main(Stirng[] args) {
Object obj1 = new Object(); // java.lang.Object@16f65612
Date obj2 = new Date(); // Mon Apr 29 12:12:36 KST 2019
}
}
System.out.println() 메소드
매개값은 콘솔에 출력할 내용인데, 매개값이 기본 타입(byte, short, int, long, float, double, boolean)일 경우, 해당 값을 그대로 출력
자바 프로그램은 운영체제에서 바로 실행되는 것이 아닌 JVM 위에서 실행
프로그램 종료(exit()
)
현재 실행하고 있는 프로세스를 강제 종료
System. exit(0);
// example
public class ExitExample {
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
if(i == 5) {
System.exit(0);
// break
}
}
System.out.println("마무리 코드");
}
}
현재 시각 읽기(currentTimeMillis()
, nanoTime()
)
컴퓨터의 시계로부터 현재 시간을 읽어서 밀리세컨드(1/1000초) 단위와 나노세컨드(1/10^9초) 단위의 long 값을 리턴
long time = System.currentTimeMillis();
long time = System.nanoTime();
자바는 클래스와 인터페이스의 메타 데이터를 java.lang 패키지에 소속된 Class 클래스로 관리
Class 객체 얻기(getClass()
, forName()
)
// 클래스로부터 얻는 방법
Class clazz = 클래스이름.class
Class clazz = Class.forName("패키지...클래스이름")
// 객체로부터 얻는 방법
Class clazz = 참조변수.getClass();
// example
Class clazz = String.class; // 1
Class clazz = Class.forName("java.lang.String"); // 2
String str = "김자바";
Class clazz = str.getClass(); // 3
클래스 경로를 활용해서 리소스 절대 경로 얻기
해당 클래스의 파일 경로 정보를 가지고 있기 때문에 이 경로를 활용해서 다른 리소스(이미지, XML, Property 파일)의 경로를 얻을 수 있음
C:\SelfJavaStudy\chap11\bin\sec01
| - exam10
| - Car.class
| - photo1.jpg
| - images
| - photo2.jpg
// 프로그램 실행 중에 이미지 파일(photo1.jpg, photo2.jpg)의 절대 경로가 필요한 경우
// Car.class를 기준으로 한 상대 경로를 이용해서 절대 경로를 얻음
String photo1Path = clazz.getResource("photo1.jpg").getPath();
String photo2Path = clazz.getResource("photo2.jpg").getPath();
문자열을 생성하는 방법과 추출, 비교, 찾기, 분리, 변환 등을 제공하는 메소드
String 생성자
자바의 문자열은 java.lang 패키지의 String 클래스의 인스턴스로 관리
example: 파일의 내용을 읽거나 네트워크를 통해 받은 데이터는 보통 byte[] 배열이므로 문자열로 변환
// 배열 전체를 String 객체로 생성
String str = new String(byte[] bytes);
// 적절하 문자셋으로 디코딩
String str = new Stirng(byte[] bytes, String charsetName);
// 배열의 offset 인덱스 위치부터 length만큼 String 객체로 생성
String str = new String(byte[] bytes, int offset, int length);
// 지정한 문자셋으로 디코딩
String str = new String(byte[] bytes, int offset, int length, String charsetName)
System.in.read()
: 키보드에서 입력한 내용을 매개값으로 주어진 바이트 배열에 저장하고 읽은 바이트 수를 리턴
String 메소드
charAt(int index)
: 특정 위치의 문자를 리턴equals(Object anObject)
: 두 문자열을 비교getBytes()
: byte[]로 리턴getBytes(Charset charset)
: 주어진 문자셋으로 인코딩한 byte[]로 리턴indexOf(String str)
: 문자열 내에서 주어진 문자열의 위치를 리턴length()
: 총 문자의 수를 리턴replace(CharSequence target, CharSequence replacement)
: target 부분을 replacement로 대치한 새로운 문자열을 리턴substring(int beginIndex)
: beginIndex 위치에서 끝까지 잘라낸 새로운 문자열을 리턴substring(int beginIndex, int endIndex)
: beginIndex 위치에서 endIndex 전까지 잘라낸 새로운 문자열을 리턴toLowerCase()
: 알파벳 소문자로 변환한 새로운 문자열을 리턴toUpperCase()
: 알파벳 대문자로 변환한 새로운 문자열을 리턴trim()
: 앞뒤 공백을 제거한 새로운 문자열을 리턴valueOf(int i)
, valueOf(double d)
: 기본 타입 값을 문자열로 리턴
문자 추출(charAt()
)
매개값으로 주어진 인덱스의 문자를 리턴(인덱스란 0부터 문자열 길이 -1 까지의 번호)
String subject = "자바 프로그래밍";
char charVBalue = subject.charAt(3); // 3번 인덱스: 프
문자열 비교(equals()
);
기본 타입(byte, char, short, int, long, float, double, boolean) 변수의 값을 비교할 때에는 == 연산자를 사용
String strVar1 = new String("신민철");
String strVar2 = "신민철";
String strVar3 = "신민철";
strVar1 == strVar2 // false
strVar2 == strVar3 // true
// 문자열만을 비교하는 equals() 메소드
strVar1.equals(strVar2) // true
strVar2.equals(strVar3) // true
바이트 배열로 변환(getBytes()
)
네트워크로 문자열을 전송하거나, 문자열을 암호화할 때 문자열을 바이트 배열로 변환하는 경우가 있음
byte[] bytes = "문자열".getBytes();
byte[] bytes = "문자열".getBytes(Charset charset);
// example
try {
byte[] bytes1 = "문자열".getBytes("EUC-KR");
byte[] bytes2 = "문자열".getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
}
바이트 배열을 다시 문자열로 변환(디코딩)할 때에는 어떤 문자셋으로 인코딩된 바이트 배열이냐에 따라서 디코딩 방법이 다름
String str = new String(byte[] bytes, String charsetName);
문자열 찾기(indexOf()
)
매개값으로 주어진 문자열이 시작되는 인덱스를 리턴
String subject = "자바 프로그래밍":
int index = subject.indexOf("프로그래밍"); // 3
// example
if( 문자열.indexOf("찾는 문자열") != -1 ) {
// 포함되어 있는 경우
} else {
// 포함되어 있지 않은 경우
}
문자열 길이(length()
)
문자열의 길이(문자의 수)를 리턴
String subject = "자바 프로그래밍";
int length = subject.length(); // 8
문자열 대치(replace()
)
첫 번째 매개값인 문자열을 찾아 두 번째 매개값인 문자열로 대치한 새로운 문자열을 생성하고 리턴
String oldStr = "자바 프로그래밍";
String newStr = oldStr.replace("자바", "JAVA"); // "JAVA 프로그래밍"
문자열 잘라내기(substring()
)
주어진 인덱스에서 문자열을 추출
substring(int beginIndex, int endIndex)
: 주어진 시작과 끝 인덱스 사이의 무자열을 추출substring(int beginIndex)
: 주어진 인덱스부터 끝까지 문자열을 추출String ssn = "880815-1234567";
String firstNum = ssm.substring(0, 6); // 880815
String secondNum = ssn.substring(7); // 1234567
알파벳 소/대문자 변경(toLowerCase()
, toUpperCase()
)
toLowerCase()
: 문자열을 모두 소문자로 바꾼 새로운 문자열을 생성한 후 리턴toUpperCase()
: 문자열을 모두 대문자로 바꾼 새로운 문자열을 생성한 후 리턴String original = "Java Programming";
String lowerCase = original.toLowerCase(); // java programming
String upperCase = original.toUpperCase(); // JAVA PROGRAMMING
equalsIsIgnoreCase()
메소드를 사용하면 대소문자 무시
문자열 앞뒤 공백 잘라내기(trim()
)
문자열의 앞뒤 공백을 제거한 새로운 문자열을 생성하고 리턴(중간의 공백은 제거하지 않음)
String oldStr = " 자바 프로그래밍 ";
String newStr = oldStr.trim(); // 자바 프로그래밍
문자열 변환(valueOf()
)
기본 타입의 값을 변환
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(double d)
static String valueOf(float f)
자바는 기본 타입(byte, char, short, int, long, float, double, boolean)의 값을 갖는 객체를 생성 가능
박싱(Boxing)과 언박싱(Unboxing)
기본 타입의 값을 줄 경우 | 문자열을 줄 경우 |
---|---|
Byte obj = new Byte(10); | Byte obj = new Byte("10"); |
Character obj = new Character('가'); | 없음 |
Short obj = new Short(100); | Short obj = new Short("100"); |
Integer obj = new Integer(1000); | Integer obj = new Integer("1000"); |
Long obj = new Long(10000); | Long obj = new Long("10000"); |
Float obj = new Float(2.5F); | Float obj = new Float("2.5F"); |
Double obj = new Double(3.5); | Double obj = new Double("3.5"); |
Boolean obj = new Boolean(true); | Boolean obj = new Boolean("true"); |
생성자를 이용하지 않고, 포장 클래스마다 가지고 있는 정적 valueOf() 메소드를 사용할 수도 있음
Integer obj = Integer.valueOf(1000);
Integer obj = Integer.valueOf("1000");
자동 박싱과 언박싱
기본 타입 값을 직접 박싱, 언박싱 하지 않아도 자동적으로 박싱과 언박싱이 일어나는 경우가 있음
example: int 타입의 값을 Integer 클래스 변수에 대입하면 자동 박싱이 일어나 힙 영역에 Integer 객체가 생성
Integer obj = 100; // 자동 박싱
자동 언박싱은 기본 타입에 포장 객체가 대입되는 경우와 연산에서 발생
example: Integer 객체를 int 타입 변수에 대입하거나, Integer 객체와 int 값을 연산하면 Integer 객체로부터 int 값이 자동 언박싱되어 연산
Integer obj = new Integer(200);
int value1 = obj; // 자동 언박싱
int value2 = obj + 100; // 자동 언박싱
문자열을 기본 타입 값으로 변환
포장 클래스의 주요 용도는 기본 타입의 값을 박싱해서 포장 객체로 만드는 것이지만, 문자열을 기본 타입의 값으로 변환할 때에도 많이 사용
parse + 기본 타입 이름
으로 되어 있는 정적 메소드가 있음num = Byte.parseByte("10");
num = Short.parseShort("100");
num = Integer.parseInt("1000");
num = Long.parseLong("10000");
num = Float.parseFloat("2.5F");
num = Double.parseDouble("3.5");
num = Boolean.parseBoolean("true");
포장 값 비교
포장 객체는 내부의 값을 비교하기 위해 ==와 != 연산자를 사용하지 않는 것이 좋음
// 동일한 값을 가지고 있지만 == 연산자의 결과는 flase
Integer obj1 = 300;
Integer obj2 = 300;
System.out.println(obj1 == obj2); // false
박싱된 값이 다음 표에 나와있는 범위의 값이라면 ==와 !=연산자로 내부의 값을 바로 비교할 수 있지만, 그 외의 경우에는 언박싱한 값을 얻어 비교를 해야 함
타입 | 값의 범위 |
---|---|
boolean | true, false |
char | \u0000 ~ \u007f |
byte, short, int | -128 ~ 127 |
수학 계산에 사용할 수 있는 메소드 제공(모두 정적 메소드)
메소드 | 설명 | 예제 코드 | 리턴값 |
---|---|---|---|
int abs(int a) | 절대값 | int v1 = Math.abs(-5); | v1=5 |
double abs(double a) | 절대값 | double v2 = Math.abs(-3.14); | v2=3.14 |
double cell(double a) | 올림값 | double v3 = Math.cell(5.3); | v3=6.0 |
double cell(double a) | 올림값 | double v4 = Math.cell(-5.3); | v4=-5.0 |
double floor(double a) | 버림값 | double v5 = Math.floor(5.3); | v5=5.0 |
double floor(double a) | 버림값 | double v6 = Math.floor(-5.3); | v6=-6.0 |
int max(int a, int b) | 최대값 | int v7 = Math.max(5, 9); | v7=9 |
double max(double a, double b) | 최대값 | double v8 = Math.max(5.3, 2.5); | v8=5.3 |
int min(int a, int b) | 최소값 | int v9 = Math.min(5, 9); | v9=5 |
double min(double a, double b) | 최소값 | double v10 = Math.min(5.3, 2.5); | v10=2.5 |
double random() | 랜덤값 | double v11 = Math.random(); | 0.0 <= v11 < 1.0 |
double rint(double a) | 가까운 정수의 실수값 | double v12 = Math.rint(5.3); | v12=5.0 |
double rint(double a) | 가까운 정수의 실수값 | double v13 = Math.rint(5.7); | v13=6.0 |
long round(double a) | 반올림값 | long v14 = Math.round(5.3); | v14=5 |
long round(double a) | 반올림값 | long v15 = Math.round(5.7); | v15=6 |
Date now = new Date();
Date 객체의 toString() 메소드는 영문으로 된 날짜를 리턴
Date now = new Date();
String strNow1 = now.toString();
// Mon Mar 11 17:19:08 KST 2024
SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일 hh시 mm분 ss초");
String strNow = sdf.format(now); // 원하는 형식의 날짜 정보를 얻음
// 2024년 3월 11ㅣㄹ 05시 19분 08호
getInstance()
메소드를 이용하면 운영체제에 설정되어 있는 시간대를 기준으로 한 Calendar 하위 객체를 얻을 수 있음Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR); // 연도를 리턴
int month = now.get(Calendar.MONTH) + 1; // 월을 리턴
int day = now.get(Calendar.DAY_OF_MONTH); // 일을 리턴
String week = now.get(Calendar.DAY_OF_WEEK); // 요일을 리턴
String amPm = now.get(Calendar.AM_PM); // 오전/오후를 리턴
int hour = now.get(Calendar.HOUR); // 시를 리턴
int minute = now.get(Calendar.MINUTE); // 분을 리턴
int second = now.get(Calendar.SECOND); // 초를 리턴