MyInterface MyClassA MyClassB DefaultMethodEx
=> 디폴트메서드를 사용하는 이유
public interface MyInterface {
public void method1(); // 인터페이스는 대부분 public 사용. 없어도 무방. 스스로추갛람
default void method2(){
System.out.println("dMyInterface의 method2() 실행");
}
}
public class MyClassA implements MyInterface{ //상속
@Override
public void method1() { //MyInterface의 내용 구현함
System.out.println("MyClassA의 method1()실행");
// 메서드1만 사용하다가 인터페이스가 업데이트되면 문제가 생김.
// 인터페이스는 상속을 받아 만드는 클래스가 반드시 있어야 한다.
// 뜬금없이 메서드2를 추가해야하는 상황이 됨 => 디폴트 메서드라는 개념생김
// 디폴트메서드가 되면 굳이 오버라이드 하지 않아도됨.
}
@Override
public void method2(){
System.out.println("MyclassA의 method2()실행");
// 원한다면 해도된다.(디폴트메서드)
}
}
public class MyClassB implements MyInterface{
@Override
public void method1() {
System.out.println("MyClassB의 method1()실행");
}
@Override
public void method2() {
System.out.println("MyClassB의 method2()실행");
}
}
public class DefaultMethodEx {
public static void main(String[] args) {
MyInterface m1 = new MyClassA();
m1.method1();
m1.method2();
MyInterface m2 = new MyClassB();
m2.method1();
m2.method2();
}
}
MyInterface2 MyClassC
public interface MyInterface2 extends MyInterface{
// 인터페이스 간 상속은 extends 사용해야함
// 부모 인터페이스인 MyInterface에서 상속받은 멤버 메서드 중 디폴트 메서드인
// method2()를 오버라이딩하여 추상 메서드로 변환.
// Interface2를 상속받는 게 있다면 method2()를 무조건 오버라이딩해줘야한다.
@Override
void method2(); //디폴트메서드를 추상메서드로 받음
void method3();
}
public class MyClassC implements MyInterface2{
@Override
public void method1() {
System.out.println("MyClassC의 method1() 실행");
}
// 1번. MyInterface에서 상속받은 추상메서드
@Override
public void method2() {
System.out.println("MyClassC의 method2() 실행");
}
// 2번. MyInterface에서 디폴트 메서드로 상속해줬으나 MyInterface2에서 추상메서드로 오버라이딩한 메서드
// MyInterface2를 구현하는 구현체는 반드시 해당 메서드를 구현해야 함.
@Override
public void method3() {
System.out.println("MyClassC의 method3() 실행");
}
// 3번. MyInterface2에서 전용으로 생성한 추상메서드
}
=> 마트의 고객센터
일반(컴파일 체크) 예외(Exception)
실행 예외(RuntimeException)
ExceptionEx -> chap03에 있다!
public class ExceptionEx {
public static void main(String[] args) {
String data = null;
System.out.println(data.toString()); //여기서는 말짱하지만 오류발생됨
}
}
String data1 = args[0];
String data2 = args[1];
System.out.println("args[0] : " + data1);
System.out.println("args[1] : " + data2);
String data1 = "100";
String data2 = "a100"; //a 때문에 정수형 변형 불가.
int value1 = Integer.parseInt(data1); // 문자형을 정수형으로 바꿔줌
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
try : 예외 발생 가능 코드
catch : 예외처리. (예외클래스 = Exception)
TryCatchEx
System.out.println("======NullPointerException========");
try {
String data = null;
System.out.println(data.toString());
}
catch (Exception e){
System.out.println("null인 데이터에서는 toString() 메서드를 사용할 수 없습니다.");
}
System.out.println("=====ArrayIndexOutOfBoundsException=======");
try{
String data1 = args[10]; //오류발생. 바로 catch로 넘어감. 이렇게하면 프로그램이 멈추지 않는다.
String data2 = args[20];
System.out.println("args[10] : " + data1);
System.out.println("args[20] : " + data2);
}
catch (Exception e){
System.out.println("배열의 최대 index 범위를 넘어서 사용하였습니다.");
}
System.out.println("=====다중 catch=======");
try{
String data1 = "100";
String data2 = "a100";
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
}
catch (NullPointerException e){
System.out.println("null을 사용하여 진행할 수 없습니다.");
}
catch (NumberFormatException e){ //e는 Exception이 발생할 때 저장되는 데이터들을 넣어놨다.
System.out.println("정수로 변환할 수 있습니다.");
System.out.println(e.getMessage()); //For input string: "a100". 오류 왜났는지
System.out.println(e.getStackTrace()); //[Ljava.lang.StackTraceElement;@1e643faf //주소
// e.printStackTrace();// 에러와 관련된 정보를 전부 보여줌.
}
// Exception 클래스는 모든 예외 클래스의 최상위 클래스이므로 여러 개의 catch문을 사용할 경우
// 가장 마지막에 입력해야 한다.
catch (Exception e){ //위에 있으면 Exception을 제외한 catch들을 오류로 표시.
System.out.println("알 수 없는 오류가 발생했습니다.");
}
| 사용하여 or 처리.
System.out.println("\n======finally 사용하기 =======");
Scanner scanner = new Scanner(System.in);
try{
System.out.println("문자를 입력해주세요 : ");
String data = scanner.nextLine();
if(data.equals("")){
data = null;
}
// System.out.println(data.toString());
System.out.println("입력된 내용 : " + data.toString());
System.out.println("여기는 정상 실행 완료 후 실행되는 부분입니다");
}
catch (NullPointerException e){
System.out.println("여기는 예외 발생시 실행되는 부분입니다.");
System.out.println("예외이유 : " + e.getMessage());
}
finally {
System.out.println("여기는 무조건 실행되는 부분입니다.");
}
System.out.println("try ~ catch가 완료된 후 실행되는 부분입니다.");
}
}
공백넣었을 때
문자넣었을 때
import java.io.*;
import java.util.Scanner;
public class TryCatchEx {
public static void main(String[] args) throws FileNotFoundException {
// String data = null;
// System.out.println(data.toString());//현재 오류나는 부분(NullPointerException)
System.out.println("======NullPointerException========");
try {
String data = null;
System.out.println(data.toString());
} catch (Exception e) {
System.out.println("null인 데이터에서는 toString() 메서드를 사용할 수 없습니다.");
}
System.out.println("=====ArrayIndexOutOfBoundsException=======");
try {
String data1 = args[10]; //오류발생. 바로 catch로 넘어감. 이렇게하면 프로그램이 멈추지 않는다.
String data2 = args[20];
System.out.println("args[10] : " + data1);
System.out.println("args[20] : " + data2);
} catch (Exception e) {
System.out.println("배열의 최대 index 범위를 넘어서 사용하였습니다.");
}
System.out.println("=====다중 catch=======");
try {
String data1 = "100";
String data2 = "a100";
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
}
// 예외처리를 하나로 모두 처리하면 Exception을 사용.
// 지정한 예외 상황만 처리하고자 하면 해당 예외 클래스를 사용해야 함.
// catch (NumberFormatException e){
// System.out.println("정수로 변환할 수 없습니다.");
// }
// catch (NullPointerException e){ //오류난다.
// System.out.println("정수로 변환할 수 없습니다.");
// }
// catch (Exception e){
// System.out.println("정수로 변환할 수 없습니다.");
// }
// 하나의 try 구문에서 여러 개의 지정된 예외처리를 하고자 한다면 catch를 여러 개 사용할 수 있다.
catch (NullPointerException e) {
System.out.println("null을 사용하여 진행할 수 없습니다.");
} catch (NumberFormatException e) { //e는 Exception이 발생할 때 저장되는 데이터들을 넣어놨다.
System.out.println("정수로 변환할 수 있습니다.");
System.out.println(e.getMessage()); //For input string: "a100". 오류 왜났는지
System.out.println(e.getStackTrace()); //[Ljava.lang.StackTraceElement;@1e643faf //주소
// e.printStackTrace();// 에러와 관련된 정보를 전부 보여줌.
}
// Exception 클래스는 모든 예외 클래스의 최상위 클래스이므로 여러 개의 catch문을 사용할 경우
// 가장 마지막에 입력해야 한다.
catch (Exception e) { //위에 있으면 Exception을 제외한 catch들을 오류로 표시.
System.out.println("알 수 없는 오류가 발생했습니다.");
}
// finally : try ~ catch 구문에서 예외가 발생하던 발생하지 않던 무조건 실행되어야 하는 소스코드를 입력하는
// 부분을 finally라고 한다. 주로 외부 리소스(파일, 네트워크 연결) 사용 시 해당 리소스를 해제하기 위한 목적으로 많이 사용함
// 자바의 가장 큰 특징 : 가비지 컬렉터 -> 비사용메모리 자동 정리. 파일, 네트워크 연결은 자동정리 안됨.
// open만 하고 close를 안하면 계속 돌고 있다.
System.out.println("\n======finally 사용하기 =======");
Scanner scanner = new Scanner(System.in);
try {
System.out.println("문자를 입력해주세요 : ");
String data = scanner.nextLine();
if (data.equals("")) {
data = null;
}
// System.out.println(data.toString());
System.out.println("입력된 내용 : " + data.toString());
System.out.println("여기는 정상 실행 완료 후 실행되는 부분입니다");
} catch (NullPointerException e) {
System.out.println("여기는 예외 발생시 실행되는 부분입니다.");
System.out.println("예외이유 : " + e.getMessage());
} finally {
System.out.println("여기는 무조건 실행되는 부분입니다.");
}
System.out.println("try ~ catch가 완료된 후 실행되는 부분입니다.");
System.out.println("\n\n ");
File file = new File("test.txt");
String str = "java file write test";
try { //file 생성 -> 왼측에 있다.
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
writer.write(str);
writer.close();
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("파일 쓰기 사용 시 오류가 발생했습니다.");
}
System.out.println("파일 쓰기 완료");
System.out.println("\n==== 파일 읽기 시작====");
FileReader fr = null;
BufferedReader reader = null;
try {
fr = new FileReader("c:\\test.txt"); //실제 파일 읽어온다(파일객체)
reader = new BufferedReader(fr); // 실제 안의 내용 읽어옴
String tmp;
while ((tmp = reader.readLine()) != null){
System.out.println("파일 내용 >> " + tmp); //안에 내용있다면 tmp에 저장
}
}
catch (IOException e){
System.out.println("파일 사용시 오류가 발생했습니다.");
System.out.println(e.getMessage());
}
finally {
try{
if(reader != null) reader.close(); //닫는 순서 중요! 리더 -> 파일
if(fr != null) reader.close();
}
catch (Exception e){
}
}
System.out.println("=====파일 읽기 완료=======");
}
}
FileInputStream TryWithResourceEx
public class FileInputStream implements AutoCloseable {
private String file;
public FileInputStream(String file){
this.file = file;
}
public void read(){
System.out.println(file + "을 읽습니다.");
}
@Override
public void close() throws Exception{
System.out.println(file + "을 닫습니다.");
}
}
public class TryWIthResourceEx {
public static void main(String[] args) {
// 이 방식으로만 해야 한다.
// 자동으로 메모리 해제
// try with resources
try (FileInputStream fis = new FileInputStream("file.txt")){
fis.read();
throw new Exception(); //예외 강제 발생
// throw : 예외 자체를 사용자가 인위적으로만듦
}
catch (Exception e){
System.out.println("예외처리 코드가 실행되었습니다.");
}
Calculator ThrowsEx
public class Calculator {
public void sum(String a,String b){
try{
int result = 0;
int num1 = Integer.parseInt(a);
int num2 = Integer.parseInt(b);
result = num1 + num2;
System.out.println("두 수의 합은 : " + result + "입니다");
}
catch (Exception e){
System.out.println("sum 함수에서 연산 시 오류가 발생했습니다.");
}
}
// 예외 발생 시 해당 메서드를 사용하는 곳으로 예외를 떠넘김
public void sub(String a, String b) throws Exception{
int num1 = Integer.parseInt(a); //오류가 발생할 가능성이 있는 소스
int num2 = Integer.parseInt(b); //오류가 발생할 가능성이 있는 소스
int result = num1 - num2;
System.out.println("두 수의 차는 : " + result + "입니다.");
}
}
public class ThrowsEx {
public static void main(String[] args) {
Calculator cal = new Calculator();
try {
cal.sum("십", "20"); //sum은 calculator에 오류처리부분이있다.
cal.sub("10A", "20"); //실제 오류 발생한 부분은 calculator 클래스인데,
// throw로 넘겼기 때문에 여기서 오류표시뜸. 이쪽에 정리하면 보기 편하다.
// 또한 예외처리를 따로 담당해주는 클래스를 만들 수 있다.
// throw는 사용하는 곳에서 예외처리하게 만듦.
}
catch (Exception e){
System.out.println("실행 시 오류가 발생했습니다.");
}
}
}
우리가 임의적으로 조작하는 것.
// TryWithResoucrsEx에서 사용함
throw new Exception();
public class BalanceInsufficientException extends Exception{ // 상속받음
// 사용자 정의 예외
// 그냥 excti
public BalanceInsufficientException(){} //기본생성자
public BalanceInsufficientException(String message){ //생성자 오버로딩으로 여러 개 사용가능
super(message); //상속을 받았을 때 부모 클래스의 생성자를 가져오는 것. 받은 메세지를 exception에 넘겨줌
}
}
public void deposit(int money) { // 기존 금액, 새로 받은 금액 더해줌
balance += money; // 이름이 다르니까 this붙일 필요 없다.
}
public void withdraw(int money) throws BalanceInsufficientException{ //매개 변수로 받아온 값 처리(money)
if(balance < money){
// 예외처리가 없을 경우
// System.out.println("출금 금액이 총 예금 금액보다 큽니다."); // 이렇게 하지 않아도 아래처럼 하면됨.
// 사용자 정의 예외를 사용함.
throw new BalanceInsufficientException("잔고 부족 : " + (money - balance) + "원 모자람");
// throw로 강제로 예외발생 -> new 매개변수로 메세지 발생.
// 원래 이곳에 try catch 해야함.
}
balance -= money;
// try{
// public void withdraw ( int money) throws BalanceInsufficientException { //매개 변수로 받아온 값 처리(money)
// if (balance < money) {
// throw new BalanceInsufficientException("잔고 부족 : " + (money - balance) + "원 모자람");
//// throw로 강제로 예외발생 -> new 매개변수로 메세지 발생.
//// 원래 이곳에 try catch 해야함.
// }
// balance -= money;
// }
// catch(Exception e) {
// System.out.println("dd");
// }
}
}
public class AccountEx {
public static void main(String[] args) {
Account account = new Account();
account.deposit(10000);
System.out.println("예금액 : " + account.getBalance());
try{
account.withdraw(30000);
}
catch (BalanceInsufficientException e){
String message = e.getMessage(); //BalanceInsufficientException 에서 메세지 받아옴
System.out.println(message); // 잔고 부족 : 20000원 모자람 이거 출력됨.
System.out.println();
// e.printStackTrace(); // 어디서 오류 났는지 정보 보여줌
// e.getStackTrace();
}
}
}
예외 객체 e를 만들기 위해 존재.
위치를 정확히 알려주기 위해 throw를 사용.
추가 : add
뺄 때 : get
수정 : set
List list = new ArrayList();
모든 타입 넣을 수 있다. 그러므로 강제형변환 문자형으로 바꿔야한다.
제네릭은 <>안에 String을 넣음으로써 형을 미리 고정시켜놓는다.
뺄 때 get을 쓸 필요 없다.
<데이터타입>
ArrayList 많이 사용. 배열과 거의 유사. 중복된다. index
HashMap 많이 사용. 중복저장이 안된다. key,value
중복저장안됨.
javascript의 배열과 자바의 리스트가 비슷하다.
배열 : 하나의 이름으로 동일한 타입의 데이터를 여러 개 저장하는 데이터 타입
ArrayList : 하나의 이름으로 동일한 타입의 데이터를 여러 개 저장하는 데이터 타입.
배열 : index 존재 (0부터 시작) 그러나 크기가 고정되어있다.
ArrayList : index 존재 (0부터 시작) 크기가 유동적이다.
=> 크기에 대한 차이를 제외하고는 모두 동일하다.
실제 현장에서는 배열보다는 ArrayList를 더 많이 사용한다.
ArrayList는 배열보다 속도는 느리지만 크기가 유동적이기에 보다 더 데이터를 효율적으로 사용할 수 있기 때문에 많이 사용되는 편이다.
ArrayListEx
import java.util.ArrayList;
import java.util.List;
//import java.util.*; 이거 해도 됨
public class ArrayListEx {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>(); //많이 사용하는 방식. 뒤의 <>에는 데이터타입 생략 가능.
System.out.println("ArrayList 생성\nlist의 길이 : " + list.size()); // list.size()의 크기 알려줌
list.add("HTML5");
list.add("CSS3");
list.add("Bootstrap5");
list.add("JS ES6");
list.add("React");
list.add("Java");
list.add("Servlet / JSP");
list.add("Spring framework");
list.add("Spring boot");
list.add("Database(Mysql)");
list.add("Python");
System.out.println("\n데이터 추가 후 arraylist의 길이 확인 : " + list.size());
// 데이터를 추가했기 때문에 arraylist가 11로 출력이 된다. 이게 바로 배열과 arraylist의 차이.
String str = list.get(5); //5번째 것을 가져온다
System.out.println("\nlist의 5번 index의 값 : " + str+"\n");
System.out.println("리스트의 전체 내용 출력 ");
for(int i =0; i<list.size(); i++){
System.out.println("리스트 " + i + "번 index의 값 : " + list.get(i));
}
System.out.println("\n=====리스트 안 데이터 삭제하기======");
list.remove(5); //5번 삭제
list.remove(2); //2번 삭제
list.remove("React"); //Java 삭제
System.out.println("\nremove 후 list 변수의 크기 : " + list.size() + "\n");
for(int i = 0; i < list.size(); i++){
System.out.println("리스트" + i +"번 index값의 : " + list.get(i));
}
// List 클래스가 ArrayList의 부모이므로 부모 타입의 변수에 자식 클래스 타입인 ArrayList 객체를 대입하여 사용
// List<String> list2 = new ArrayList<String>(); // 위 아래 중 원하는 방식으로 사용하면 된다
}
}