Eclipse 프로젝트 생성
new Java project를 하면 여러 선택지가 나옴.
Project layout
- use project folder as root for sources and class files
- 빌드 전 소스코드와 빌드 후 생성된 결과물이 root에 한번에 생김
 
 - Create separate folders for sources and class files
- 빌드 전 소스코드와 빌드 후 생성된 결과물을 다른 폴더에 저장
 
 
- use project folder as root for sources and class files
 Module
Create module-info.java file
서로 다른 프로젝트 a,b에 대해 a에서 선언한 클래스를 b에서 불러와 사용할 수 있도록 하는 파일
1 2 3 4
// export module common.widget { exports com.logicbig; // 외부에 노출하고싶은 패키지 }
1 2 3 4 5
// import module data.widget { requires common.widget; // 사용할 패키지 requires java.sql; }
Hello world
src아래HelloWorldApp.java파일 생성아래와 같이 작성
1 2 3 4 5
public class HellowWorldApp { public static void main(String[] args) { System.out.println("Hellow World!!"); } }
- 클래스명은 파일명과 같아야함.
 - 실행하는 파일에서, 파일명과 같은 클래스명안에, 항상 
main함수는 있어야함. 
Run을 눌러 실행
프로그래밍 구성
자료형
- 원시타입
- 정수형 : int, long
 - 소수형 : float, double
 - 문자형 : char (‘’ 로 묶음)
 - boolean
 
 - 클래스타입
- String : “” 로만 묶어야함. 안에 ““를 입력하고 싶으면 \ 사용
- .length()
 - .replace(a, b) : a문자열을 찾아 b로 변경
 - .equals() : 같은지 확인
 
 
 - String : “” 로만 묶어야함. 안에 ““를 입력하고 싶으면 \ 사용
 
숫자와 연산
- Math 클래스
- 다양한 연산 메소드, 상수 제공
 
 
캐스팅
앞에
(자료형)을 붙여서 함1 2
int e = (int) 1.1; double b = (double) e;
정수 -> String
1
String f = Integer.toString(1);
배열
- 선언
- 리터럴 : 
String[] bear = {"kloud", "Cass", "Guiness"}; String[] bear = new String[3];
 - 리터럴 : 
 이차원배열
리터럴
1 2 3 4 5
String[][] users = { {"egoing", "1111"}, {"jinhuck", "2222"}, {"youbin", "3333"} }
new
1
String[][] users = new String[3][2];
- 동적배열 : 
List사용 
반복문
for
- 일반적 사용
 
1 2 3 4 5
double[] dividendRates = { 0.5, 0.3, 0.2 }; double[] dividend = new double[3]; for (int i = 0; i < dividendRates.length; i++) { dividend[i] = income * dividendRates[i]; }
- 배열에서 가져오기
 
1 2 3 4 5
int[] score = { 78, 70, 65, 98, 58 }; int sum = 0; for (int i : score) { sum += i; }
while : 다른 언어와 같음.
프로그래밍 시작하기
입력과 출력
입력 다이얼로그
1 2 3
import javax.swing.JOptionPane; ... String id = JOptionPane.showInputDialog("Enter a Id");
Scanner
1 2 3 4 5 6 7 8
import java.util.Scanner; ... Scanner in = new Scanner(System.in); int a = in.nextInt(); // int형 입력 및 리턴 float b = in.nextFloat(); boolean c = in.nextBoolean(); String d = in.next(); // String 형 입력 및 리턴 (공백을 기준) String e = in.nextLine(); // String 형 입력 및 리턴 (개행을 기준)
arguments & parameter
- 가변인자
void sum(String a, String...str)와 같이 작성하여, 여러개 받을 수 있도록 하는거.- 내부적으로는 배열로 처리한다.
 
 - main 함수의 args 에 값 넣고 실행하는 방법
Run옆에 화살표 클릭Run configuration클릭- ` Arguments` 클릭
 - “JAVA APT 508” “123.0” 과 같이 넣기. 공백으로 구분.
 
 
직접 컴파일
컴파일 하고자하는 파일이 있는 곳으로 이동.
javac [파일이름].java하면.class파일 생성클래스 파일 있는 곳으로 이동
java [파일이름]하면 실행됨.class확장자를 붙이지 않음또는
.java파일을 직접 실행시켜도 된다. 이때는 확장자를 붙임
직접 컴파일 : 라이브러리 사용
javac -cp ".;lib" OkJavaGoInHome.java-cp:--class-path라는 의미. 구분자를 통해 컴파일할 폴더를 연결 가능.;lib:;는 구분자..(현재폴더)와lib를 컴파일 하라는 뜻.
실행도 비슷하게
java -cp ".;lib" OkJavaGoInHome으로 실행.
직접 컴파일 : arguments
java OkJavaGoInHomeInput "JAVA APT 507" 15.0
자바용어
패키지, 클래스, 메소드, 변수
- 패키지 : 비슷한 성격의 클래스를 모은것
- java.lang : import 없이 사용가능
 
 - 클래스 : 서로 연관된 변수와 메소드를 모아 이름을 붙인 것
 
- 패키지 : 비슷한 성격의 클래스를 모은것
 인스턴스 : 클래스를 컴퓨터 상에서 실체화 한 것
PrintWriter p1 = new PrintWriter("result1.txt")
상속
throws : 메소드 옆에 붙여 어떤 에러를 던질 수 있는지를 표시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
public static void main(String[] args) { Test test = new Test(); try { test.test("1", "r"); } catch(NumberFormatException e) { System.out.println("입력하신 값은 숫자가 아닙니다."); } } class Text { public void test(String a, String b) throws NumberFormatException { try { int sum = Integer.parseInt(a) + Integer.parseInt(b); // 숫자가 아닐시 NumberFormatException 발생 System.out.pringln("합은 " + sum); } catch(NumberFormatException e) { throw e; } } }
클래스
생성자 : public + 클래스이름으로 선언
1 2 3 4 5 6 7 8 9 10 11
public class AccountingMethodApp { public double valueOfSupply; public double vatRate; public double expenseRate; public AccountingMethodApp(double valueOfSupply, double VatRate, double expenseRate) { this.valueOfSupply = valueOfSupply; this.vatRate = VatRate; this.expenseRate = expenseRate; } ...
static : 정적 멤버 선언.(static 변수 : 정적필드, static 메소드 : 정적 메소드)
객체(인스턴스)에 소속된 멤버가 아니라 클래스에 고정된 멤버.
클래스로더가 클래스를 로딩해서 메소드 메모리 영역에 적재할 떄, 클래스별로 관리한다.
정적멤버는 heap이 아닌 static 영역에 할당됨. 프로그램이 종료될 때까지 할당된 상태이므로, static을 남발할 시 프로그램 성능에 악영향을 끼침
인스턴스를 생성하지 않아도 호출 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
public class AccountingMethodApp { public static double valueOfSupply; public static double vatRate; public static double expenseRate; public static void print() { System.out.println("Value of supply : " + valueOfSupply); System.out.println("VAT : " + getVAT()); System.out.println("Total : " + getTotal()); System.out.println("Expense : " + getExpense()); System.out.println("Income : " + getIncome()); } public static double getIncome() { return valueOfSupply - getExpense(); } public static double getExpense() { return valueOfSupply * expenseRate; } public static double getTotal() { return valueOfSupply + getVAT(); } public static double getVAT() { return valueOfSupply * vatRate; } } public class Test { public static void main(String[] args) { AccountingMethodApp.valueOfSupply = 10000.0; AccountingMethodApp.vatRate = 0.5; AccountingMethodApp.expenseRate =0.1; AccountingMethodApp.print(); } }
static 메소드에서는 static 메소드와 변수만 참조가능하다.
제어문
비교
일반적인 상황에서는 == 등의 비교연산자 사용
String은
equals()메소드 사용.==로 비교시 메모리 주소를 비교..equals()로 비교해야 내용을 비교한다.이유
원시데이터 타입일 경우, 변수가 선언되면 stack에 공간이 할당되고, 그 곳에 실제 값이 들어가게 된다. 그래서
==연산자는 변수가 가리키는 값을 비교한다.하지만 String과 같이
java.lang.Object에서 파생된 클래스들은 원시 데이터 타입이 아니다.new로 생성되면heap에 새로운 공간이 할당되어 값을 저장하고, 변수는 그 값이 저장된 메모리 주소를 가리키게 된다. 따라서 클래스를==로 비교하면 메모리 주소를 비교하게 되는 것이다.하지만
문자열 리터럴로 String을 생성한 경우, 이미 같은 문자열을 생성한 적이 있다면 새로 메모리 공간을 할당하지 않고 새로운 변수는 기존 문자열이 저장된 메모리의 주소를 가리키게 된다. 따라서==연산시 true가 나온다. 그래도 내용을 비교하려면 일단.equals()로 비교하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// 결과 : False String a = new String("1234"); String b = new String("1234"); if (a == b) { System.out.println("TRUE"); } else { System.out.println("False"); } // 결과 : TRUE (같은 메모리 주소이기에) String c = "1234"; String d = "1234"; if (c == d) { System.out.println("TRUE"); } else { System.out.println("False"); } // 결과 : False (다른 메모리 주소이기때문) if (a == c) { System.out.println("TRUE"); } else { System.out.println("False"); }
instanceof
객체가 클래스의 인스턴스냐.
a instanceof A다형성에 따라,
자식 클래스의 객체 instanceof 부모 클래스하면true가 나온다. 반대는 false
메소드
접근제어자
- public : 클래스 외부에서 접근 가능
 - private : 클래스 외부에서 접근 불가능
 - protected : 같은 패키지 내에 있거나, 상속받은 경우에만 접근 가능함.
 - package-private : 패키지 내에서만 접근 가능
 
객체지향프로그래밍
클래스(형식)
- 한 파일에 여러개를 넣을 수 있지만, public 클래스는 파일이름과 같은 클래스에 하나만 생성가능.
 - 자바의 소스코드를 실행할 때, 소스코드 파일명과 동일한 public 클래스를 컴파일해서 그 클래스의 main 메소드를 실행하는 걸로 약속 되어있다.
 - 소스코드를 컴파일할때 그 안에 들어있는 클래스는 따로따로 
.class파일로 컴파일된다.- 한 파일 안에 여러 개의 클래스가 있으면, 각각 따로 
.class파일이 나오도록 컴파일 된다는 것 
 - 한 파일 안에 여러 개의 클래스가 있으면, 각각 따로 
 
생성자와 this
생성자 : 리턴형을 없앤 메소드 형식. 접근제어자는 public이어야함.
1 2 3 4 5 6
class Print { public String delimiter = ""; public Print(String delimiter) { this.delimiter = delimiter; } ...
this
- 인스턴스를 가리키는 예약어.
 
OOP
- https://seongil-shin.github.io/posts/oop/
 
상속
extends
1
2
3
4
5
6
7
8
9
10
class Cal {
	public int sum(int v1, int v2) {
		return v1 + v2;
	}
}
class Cal3 extends Cal{
	public int minus(int v1, int v2) {
		return v1 - v2;
	}
}
override
1
2
3
4
5
6
7
8
9
10
11
12
class Cal3 extends Cal{
	@Override
    public int sum(int v1, int v2) {
		System.out.println("Cal3!!!");
		return v1 + v2;
	}
    // overloading
    public int sum(int v1, int v2, int v3) {
        return v1 + v2 + v3;
    }
}
- 이름, 매개변수가 같은 메소드의 구현만 다르게 하는 것.
 - @Override 어노테이션을 붙이는 것이 좋다.
 - vs overload
- 이름은 같으나 매개변수가 다른 메소드.
 - 같은 클래스 내에서도 선언가능
 - 생성자도 이와 같이 오버로딩 가능
 
 
this super
- super : 부모 클래스를 가리키는 키워드.
- 자식클래스에서 super를 이용하여 접근 권한이 부여된 부모클래스의 변수와 메소드에 접근할 수 있다.
 
 
1
2
3
4
5
6
7
8
9
10
11
12
class Cal {
	public int sum(int v1, int v2) {
		return v1 + v2;
	}
}
class Cal3 extends Cal{
	@Override
	public int sum(int v1, int v2) {
		System.out.println("Cal3!!!");
		return super.sum(v1, v2);
	}
}
super() 를 통해 부모 클래스의 생성자 호출가능
자식 클래스에서 생성자가 없으면 암묵적으로 부모 클래스의 생성자가 호출됨
하지만 아래와 같이 인자를 받는 생성자만 부모클래스에 있다면, 자식 클래스에서도 생성자를 명시적으로 호출하여 부모 클래스의 생성자를 호출해야한다.
- super() 는 인자가 없는 생성자를 호출하는 것이므로.
 - 마찬가지로 어떤 클래스에 인자를 받는 생성자만 있는데, 인자를 넣지않고 인스턴스를 생성하면 컴파일 오류가 난다.
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Cal {
	int v1, v2;
	public Cal(int v1, int v2) {
		this.v1 = v1;
		this.v2 = v2;
    }
	public int sum() {
		return this.v1 + this.v2;
	}
}
class Cal2 extends Cal {
	int v3;
	public Cal2(int v1, int v2, int v3) {
		super(v1, v2);
		this.v3 = v3;
    }
	@Override
	public int sum() {
		return super.sum() + this.v3;
	}
}
Java 인터페이스
인터페이스
앞으로 만들 클래스의 메소드 규격을 선언할 수 있음
1 2 3 4 5 6 7 8 9
interface Calculable { int sum(int v1, int v2); } class RealCal implements Calculable { @Override public int sum(int v1, int v2) { return v1 + v2; } }
- 이떄도 
@Override어노테이션은 들어간다. 
- 이떄도 
 여러개의 인터페이스를 동시에 적용할 수 있음
1 2 3 4 5 6 7
interface Calculable { int sum(int v1, int v2); } interface Printable { void print(); } class RealCal implements Calculable, Printable {
interface 내부에서 변수를 정의할 수 있음. 다만 이때는 반드시 초기화 되어야함. 인터페이스를 적용한 클래스는 변수를 다시 대입할 수 없음
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
interface Calculable { double PI = 3.14; int sum(int v1, int v2); } class RealCal implements Calculable { public int sum(int v1, int v2) { return v1 + v2; } } public class InterfaceApp { public static void main(String[] args) { RealCal c = new RealCal(); System.out.println(c.sum(2, 1)); System.out.println(c.PI); } }
interface도 상속이 가능
1 2 3 4 5 6 7
interface Calculable { double PI = 3.14; int sum(int v1, int v2); } interface Printable extends Calculable { void print(); }
다형성
클래스의 인스턴스를 변수로 선언할 떄, 해당 클래스의 데이터타입으로 선언하지 않고
부모 클래스나 인터페이스를 데이터 타입으로 선언할 수 있다. 이러한 특성을 다형성이라고 부른다.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
interface Calculable { double PI = 3.14; int sum(int v1, int v2); } interface Printable { void print(); } class RealCal implements Calculable, Printable { public int sum(int v1, int v2) { return v1 + v2; } public void print() { System.out.println("this is RealCal!!!"); } }
- RealCal 인스턴스를 Calculable 타입으로 선언하면, Printable 메소드를 사용할 수 없다. 반대도 마찬가지.
 
자식 클래스의 객체 instanceof 부모 클래스하면true가 나온다.
추상클래스
인터페이스의 일부 메소드를 클래스 내에서 구현시켰을때 사용.
구현하지 않은 메소드의 리턴값 앞과 클래스 앞에
abstract를 붙여야한다1 2 3 4 5 6 7 8 9 10 11 12 13
interface Calculable { double PI = 3.14; int sum(int v1, int v2); int minus(int v1, int v2); } abstract class RealCal implements Calculable { public int sum(int v1, int v2) { return v1 + v2; } public abstract int minus(int v1, int v2); // 메소드는 없어도 되긴함 }
enum
- 상수의 집합. class 선언시 class 대신에 enum을 적어주면 된다.
 - 상수를 적을 땐, 타입이나 값을 지정할 필요없음.
 - 상수들의 이름만 콤마로 구분하고 가장 마지막에 세미콜론을 넣어주자.
 - Enum의 부모는 무조건 
java.lang.Enum따라서 다른 것을 상속받으면 안됨. 
final
- 클래스, 메소드, 변수에 선언할 수 있음.
 - 상속, override, 변경할 수 없다는 의미. 
const같은 거. - 변수에서는 더 이상 변경할 수 없다는 의미
- 인스턴스, 클래스 변수에 final를 쓸땐, 선언과 동시에 초기화 해야함.
 - 매개변수, 지역변수에 final을 쓸 땐, 굳이 초기화하지 않아도 된다.(지역변수의 경우 첫 초기화시 값이 고정됨.)
 
 
예외
예외 처리
try - catch로 가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
try { System.out.println(2); System.out.println(scores[3]); //ArrayIndexOutOfBoundsException // 여기까지 실행 -> catch(ArrayIndexOutOfBoundsException e)문으로 이동 System.out.println(3); System.out.println(2/0); //ArithmeticException System.out.println(4); } catch(ArithmeticException e) { System.out.println("잘못된 계산이네요."); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("없는 값을 찾고 계시네요 ^^"); } catch(Exception e) { System.out.println("알수 없는 에러"); } finally { System.out.println("무조건 실행") }
- catch는 위에서부터 먼저 검사하여, 에러의 타입이 처음 맞는 곳에 들어간다.
 - 일치하는 곳이 없으면 throw 됨.
 - Exception 클래스는 모든 에러클래스의 부모로, 마지막 catch 문에 Exception을 추가하면 그 곳에 들어간다.
 - Exception 클래스는 
Throwable클래스를 상속받고 있어, Throwable 클래스의 메소드도 사용가능하다. - finally 로 try가 끝날시, 또는 catch가 끝날 시 실행될 코드를 작성할 수 있다.
 
uncheked Exception vs checked Exception
- unchecked exception : 컴파일은 되지만, runtime 중에 발생할 수 있는 exception. 
RuntimeException클래스로부터 상속된 예외 - cheked Exception : try-catch로 잡지 않으면 컴파일이 안되는 에러. 
Throwable를 상속받은 클래스 중RuntimeException을 제외한 모든 에러와 예외들. 
try-with-resource
Java SE7 부터 추가된 구문
자원을 잡고, 놓아주는 과정을 try-catch-finally로 하면 복잡하기에 이를 간단히 해주는 구문
아래와 같이 try 문에 괄호를 추가하여 그 안에 사용할 자원을 정의한다.
- 자원은 여러개 넣을 수 있으며, 세미콜론(;)으로 구분한다. 마지막 객체에는 넣지 않음.
 - 전체 try문이 종료되면 생성된 인스턴스는 자동으로 종료되기에 명시적으로 close를 이용하지 않아도 된다.
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// 전 try { f = new FileWriter("data.txt"); f.write("Hello"); } catch(IOException e) { e.printStackTrace(); } finally { if (f != null) { try { f.close(); } catch (IOException e) { e.printStackTrace(); } } } // 후 try (FileWriter f = new FileWriter("data.txt")) { f.write("Hello"); } catch (IOException e) { e.printStackTrace(); }
throw
예외를 상위로 미루어 처리하는 것.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public void test(String a, String b) throws NumberFormatException { int sum = Integer.parseInt(a) + Integer.parseInt(b); System.out.println("합 : " + sum); } public void test(String a, String b) throws NumberFormatException { try { int sum = Integer.parseInt(a) + Integer.parseInt(b); System.out.println("합 : " + sum); } catch(NumberFormatException e) { System.out.println("숫자형 문자가 아닙니다.") throw e; } }
예외처리 전략
- 커스텀 예외 클래스를 만들때는, 꼭 try-catch로 묶어줄 필요가 있을 때만 Exception 클래스를 확장한다.
 - 일반적으로 실행시 예외를 처리할 수 있는 경우에만 RuntimeException을 확장한다.
 - catch 블록을 공백으로 놔두지 않는다.
 
익명클래스
다음과 같은 경우 사용함
- 프로그램내에서 일시적으로 사용되어야하는 객체
 - 재사용성이 없고, 확장성을 활용하는 것이 유지보수에서 더 불리할 때
 
문법
1
2
3
부모 클래스 [필드|변수] = new 부모클래스(매개값,...) {
};
구현법
- 필드의 초기값
 - 로컬변수의 초기값
 - 매개변수의 매개
 
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class Insect {
	void attack(){
		System.out.println("곤충은 공격을 한다");
	}
}
public class Anonymous {
	//★★방법 1 : 필드에 익명자식 객체를 생성
	Insect spider1 = new Insect(){
		String name = "무당거미";
		void cobweb(){
			System.out.println("사각형으로 거미줄을 친다.");
		}
		@Override
		void attack() {
			System.out.println(name + " 독을 발사한다.");
		}
	};
	//★★방법2 : 로컬변수의 초기값으로 대입
	void method1(){
		Insect spider2 = new Insect(){
			String name = "늑대거미";
			//거미줄을 치다.
			void cobweb(){
				System.out.println("육각형으로 거미줄을 친다.");
			}
			@Override
			void attack() {
				System.out.println(name + " 앞니로 문다.");
			}
		};
		//로컬변수이기 때문에 메서드에서 바로 사용
		spider2.attack();
        // 아래 참고. 접근 불가능
        spider2.cobweb();
	}
	//★★방법3 : 익명객체 매개변수로 대입
	void method2(Insect spider){
		spider.attack();
	}
}
참고
- 익명자식객체에서 새롭게 정의된 필드와 메소드는 자식객체 레벨에서만 사용되기 때문에 외부에서는 사용할 수 없음
 - 익명객체를 받아준 변수는 부모타입의 클래스이기 때문에 부모레벨에서 정의된 필드나 메서드만 사용이 가능
 
자바의 신
패키지
- import 문을 통해 패키지 사용 가능
 - 자바파일이 컴파일 될 때, import 된 클래스도 같이 컴파일 된다.
 - import로 다른 패키지 접근하기.
- import (루트디렉토리제외) 경로.클래스이름; //한 클래스만 참조
 - import (루트디렉토리제외) 경로.*; //마지막 폴더 아래 모든 클래스 참조
 
 
String
- StringBuffer : Thread safe, 속도 느림, 여러 쓰레드가 그 변수를 접근할 일이 있을때.
 - StringBuilder : Thread unsafe, 속도 빠름, 하나의 메소드 안에서 선언하고 더할 경우.
- 문자열을 합칠때, StringBuilder의 append 메소드를 사용하면 String에서 
+연산자를 사용할때보다 속도가 빠르다. 
 - 문자열을 합칠때, StringBuilder의 append 메소드를 사용하면 String에서 
 
제네릭
클래스, 메소드를 다양한 타입에서 사용할 수 있도록 해주는 것
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
// 클래스에서 public class GenericDTO<T> implements Serializable { private T object; public void setObject(T obj) { this.object = obj; } public T getObject() { return object; } } //호출 GenericDTO<String> dto1 = new GenericDTO<String>(); GenericDTO<StringBuffer> dto2 = new GenericDTO<StringBuffer>(); //메소드에서 //제네릭 메소드 public <T> T genericMethod(T c, T addValue) { System.out.println(addValue); System.out.println(c); return c; } //Bounded Generic 메소드 public <T extends Car> void genericMethod(WildcardGeneric<T> c, T addValue) { c.setWildcard(addValue); T value = c.getWildcard(); System.out.println(value); } //두 개이상의 제네릭 메소드 public <S, T extends Car> void genericMethod(WildcardGeneric<T> c, T addValue, S another) { c.setWildcard(addValue); T value = c.getWildcard(); System.out.println(value); }
<?>: 와일드카드매개변수에서 사용할 때, 어떤 타입이 올지 모르는 경우 사용
1
public void wildcardStringMethod(WillcardGeneric<?> c);
<? extends Car>- Car나 Car 자손들만 들어갈 수 있음.
 
<? super T>- T나 T 조상만 들어갈 수 있음.
 
자료형
- Collection 인터페이스
- List : 동적으로 변하는 배열. 하위 클래스의 부모
- ArrayList : 확장가능한 배열. Thread safe 하지 않음
 - Vector : 확장 가능한 배열. Thread safe 함.
 - Stack : LIFO. Vector 확장
 - LinkedList : 한 데이터가 자신의 앞 뒤에 무엇이 있는지 알고 있음.
 
 - Set : 중복 방지. 원하는 값이 있는지 확인하는게 주임무
- HashSet : 순서가 전혀 필요없는 데이터를 해쉬 테이블에 저장함. 성능이 가장 좋음
 - TreeSet : red-black tree. Hash보단 느림
 - LikedHashSet : 연결된 목록 타입으로 구현된 해시테이블에 데이터를 저장. 저장된 순서에 따라 값이 정렬되며 성능이 가장 느림.
 
 - Queue : FIFO
- PriorityQueue
 - Deque : 맨앞, 맨뒤에 값을 넣거나 뺄 수 있음
 
 
 - List : 동적으로 변하는 배열. 하위 클래스의 부모
 - Map 인터페이스 : key-value로 이루어져있음.
- HashMap : key-velue로 저장만 함.
 - TreeMap : 값을 저장하면서 키를 정렬한다.
 - LinkedHashMap
 - Hashtable
 
 
// 이후로는 키워드만
쓰레드
- 한 코어에 하나의 쓰레드 실행
 - Runnable 인터페이스, Thread 클래스로 생성가능
 
파일 IO
- File, Files
- File 클래스 : 파일 및 파일 경로정보 포함. 심볼릭링크 같이 유닉스계열에서 사용가능한 기능을 제공하지 않음
 - Files 클래스 : JDK 7 이상. 모든 메소드가 static이라 별도의 객체 생성이 없어 더 편리하다.
 
 - InputStream, OutputStream
- Stream은 byte를 처리하기 위한 것. 네트워크를 처리할 때 많이 사용한다.
 
 - Reader, Writer
- char 기반의 문자열을 처리하기 위한 클래스.
 - 일반적인 텍스트 에디터로 볼 수 있는 파일들을 위한 클래스.
 
 - 텍스트 파일 읽기, 쓰기
- FileReader, BufferedReader : 텍스트 파일 읽기
 - FileWriter : 텍스트 파일 쓰기
 
 - Scanner
- 텍스트 기반 기본 자료형이나 문자열 데이터를 처리하기 위한 클래스
 - 사용자로부터 입력을 받을 수 있다.
 
 
Serializable 인터페이스
- 개발자가 만든 클래스가 파일에 읽거나 쓸 수 있도록 하거나, 다른 서버로 보내거나 받을 수 있도록하려면 반드시 구현해야함.
 - 인터페이스를 구현한 다음에 serialVersionUID를 지정하는 걸 권장받음. 해당 클래스의 버전을 명시하는 것.
- UID가 다른 클래스는 이름이 같은 클래스여도 다른 클래스로 인식.
 - 별도로 지정하지 않으면 컴파일시 자동 지정됨.
 
 - 객체 저장 : ObjectOutputStream 클래스 사용
 - 객체 읽기 : ObjectInputStream 클래스 사
 
자바 NIO
- 스트림이 아닌 채널과 버퍼를 사용함
- 채널 : 물건을 중간에처 처리하는 도매상
 - 버퍼 : 도매상한테 물건을 사고, 소비자에게 파는 소매상
 
 
네트워크
- TCP 통신
- Socket 클래스
- 데이터를 보내는 쪽(클라이언트)에서 객체를 생성하여 사용함.
 - 데이터를 받는 쪽(서버)에서 클라이언트 요청을 받으면, 요청에 대한 socket 객체를 사용하여 데이터를 처리함.
 - Socket 객체를 직접 생성해야함.
 
 - SeverSocket 클래스
- 서버에서 사용하는 클래스. 객체는 클라이언트 요청이 생기면 Socket 객체를 생성하여 전달해줌.
 - 생성자와 2개의 메소드만 알아도 네트워크 프로그래밍이 가능하다.
 - 클라이언트에서 접속을 하면 Socket 객체를 생성함.
 
 
 - Socket 클래스
 UDP 통신
- DatagramSocket 클래스
- 보내는 역할과 받는 역할 모두 수행할 수 있음.
 
 - DatagramPacket 클래스
- 스트림을 사용하지 않고 데이터를 주고 받음.
 
 
- DatagramSocket 클래스
 - Http 요청
- URL 클래스 : 아주 간단한 요청 처리가능. 별로 추천하진 않음
 - Apache의 HttpComponents : 일반적으로 많이 사용함
 
 
자바 버전별
Java 7
숫자표현방법
- 진수
- 2진수 : 0b
 - 8진수 : 0
 - 16진수 : 0x
 
 - 천단위 언더바 : 1_000_000
 
- 진수
 switch 문에서 String 사용가능
제네릭을 쉽게 사용할 수 있는 Diamond
1
GenericDTO<String> dto1 = new GenericDTO<>();
- 이렇게 뒤는 생략가능하게 하는 거
 
예외 처리시 다중 처리가능
1 2 3
catch(IllegalArgumentException | FileNotFoundException | NullPointException e){ e.printStackTrace(); }
- 위와 같이 다중으로 에러를 받을 수 있음.
 
fork/join 관련 클래스
- cpu 멀티코어를 쉽게 사용하기 위해 만들어짐. 여러개로 나누어 계산한 후 결과를 모은다.
 - 쓰레드 신경 안써도 JVM이 자동으로 처리하고, worker의 개수는 CPU의 개수만큼 증가한다.
 
NIO2
- 파일의 속성, 심볼릭 링크까지 처리가능. 어떤 파일이 변경되었는지 확인할 수 있는 WatchService 클래스 제공
 - File을 대체하는 클래스 : java.nio.file 에 있음
- Paths
 - Files : 기존 File 클래스를 보완.
 - FileSystems : 파일시스템에 대한 정보를 처리
 - FileStore : 파일을 저장하는 디바이스, 파티션, 볼륨 등에 대한 정보를 처리
 
 - SeekableByteChannel(random access) : 바이트기반 채널을 처리
 - NetworkChannel 및 MulticastChannel
 - AsynchronousFileChannel : 비동기 처리 파일 채널
 
JDBC 4.1 : SQL Query를 쉽게 수행할 수 있는 RowSet의 객체를 쉽게 만들어주는 클래스 포함
TransferQueue : 메세지처리에 사용
Objects 클래스 : Object와 같은 static한 메소드 제공. 넘어온 객체가 null이어도 예외가 발생하지 않음
Java8
Lambda 표현식
- 익명클래스의 가독성을 올리기 위해 사용됨.
 - 구현해야할 함수가 하나일때만 사용가능. (default, static 제외)
 - js 화살표함수처럼 사용.
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
// 이전 private void calculateClassic() { Calculate claculateAdd = new Calculate() { //Calculate 는 Functional 인터페이스 @Override public int operation(int a, int b) { return a+b; } }; System.out.println(calculateAdd.operation(1,2)); } // 이후 private void calculateLambda() { Calculate calculateAdd = (a,b) -> a+b; System.out.println(calculateAdd.operation(1,2)); } // 이전 new Thread(new Runnable() { @Override public void run() { System.out.println("Thread run"); } }).start(); // 이후 new Thread(()->System.out.println("Thread run")).start(); // Thread 생성자로는 Runnable을 넣어줘야하므로 이렇게 해줘도 알아서 Runnable로 들어감.
Functional 인터페이스 : java.util.function 패키지에 속함. 추상메서드가 오직 하나인 인터페이스를 뜻하므로 람다식과 호흡이 좋음.
- Predicate : test()라는 메소드 존재. 두 개의 객체를 비교할 때 사용하고 boolean을 리턴함.
 - Supplier : get() 메소드 존재. 리턴값은 generic으로 선언된 타입을 리턴함
 - Consumer : accept()라는 매개변수를 하나 갖는 메소드가 존재. 리턴값은 없음.
 - Function : apply()라는 하나의 매개변수를 갖는 메소드 존재. 리턴값 존재.
 - UnaryOperator : apply()라는 하나의 매개변수를 갖는 메소드가 있음. 리턴값 존재.
 - BinaryOperator : apply()라는 두 개의 매개변수를 갖는 메소드가 있음. 리턴값 존재.
 
Stream : 연속된 정보를 처리할 때 사용함.
- 배열에는 사용할 수 없지만, 컬렉션에는 사용가능. 따라서 배열을 List로 바꾼다음 사용.
 - .stream() : 스트림 생성. 컬렉션을 스트림 객체로 변환함. 변환 후 중개, 중단 연산 사용
 - 중개연산 : filter(), map(), flatMap(), sorted()
 - 종단연산 : forEach(), toArray(), anyMatch(), allMatch(), nonMatch(), findFirst(), any(), reduce(), collector()
 - 메소드 참조. 데이터가 바로 메소드의 매개변수로 들어가도록 하는 법
- ` .forEach(System.out::println)
,.forEach(ContainingClass::staticMethodName)` 
 - ` .forEach(System.out::println)
 
Optional : null이 올 수 있는 값을 감싸기 위해 사용. 값이 null이더라도 NPE이 발생하지않음
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
// Java8 이전 List<String> names = getNames(); List<String> tempNames = names != null ? names : new ArrayList<>(); // Java8 이후 List<String> nameList = Optional.ofNullable(getNames()) .orElseGet(() -> new ArrayList<>()); // Java8 이전 public String findPostCode() { UserVO userVO = getUser(); if (userVO != null) { Address address = user.getAddress(); if (address != null) { String postCode = address.getPostCode(); if (postCode != null) { return postCode; } } } return "우편번호 없음"; } public String findPostCode() { // 위의 코드를 Optional로 펼쳐놓으면 아래와 같다. Optional<UserVO> userVO = Optional.ofNullable(getUser()); Optional<Address> address = userVO.map(UserVO::getAddress); Optional<String> postCode = address.map(Address::getPostCode); String result = postCode.orElse("우편번호 없음"); // 그리고 위의 코드를 다음과 같이 축약해서 쓸 수 있다. String result = user.map(UserVO::getAddress) .map(Address::getPostCode) .orElse("우편번호 없음"); }
- 결과가 null이 될 수 있으며, null에 의해 오류가 발생할 가능성이 매우 높을 때 반환값으로만 사용
 
인터페이스의 기본 메소드
1 2 3 4 5
public interface Vehicle { public default void doSomething(int n) { System.out.println("doSomething(Vehicle)"); } }
- 위와 같이 
default키워드와 함께 인터페이스의 디폴트메소드 선언가능 - 다중 implements 시 같은 메소드가 default라면,
- 컴파일 오류 발생. override 해줘야힘
 
 - 상속, implements 시 같은 메소드가 구현되어있다면
- 상속 메소드가 사용됨.
 
 
- 위와 같이 
 날짜 관련 클래스 추가
- 불변 클래스 추가 : java.time.ZonedDateTime, java.time.LocalDate
 - java.time.format.DateTimeFormatter : thread safe하고 빠른 클래스
 
병렬배열 정렬
- Arrays 클래스 : 배열을 처리하기에 좋은 여러 static 메소드를 가지고 있음.
- binarySearch(), fill(), sort() 등
 
 - parallelSort() : Fork-Join 프레임웍이 내부적으로 사용됨. 여러 쓰레드로 수행되어 속도는 더 빠르다.
 
- Arrays 클래스 : 배열을 처리하기에 좋은 여러 static 메소드를 가지고 있음.
 StringJoiner : 순차적으로 나열되는 문자열을 처리할 때 사용함.
출처
https://www.boostcourse.org/cs128
자바의 신
https://mangkyu.tistory.com/70
https://limkydev.tistory.com/226