God of Java #1

11 minute read

God of Java #1

1. 프로그래밍이란 무엇인가?

사람과 컴퓨터 사이의 언어

자바의 가장 작은 단위는 클래스
  • public : 접근제어자
  • class : 클래스 선언을 나타내는 예약어
  • DoorLockManager : 클래스 이름
클래스는 상태와 행위를 가진다.
  • 상태 : 클래스의 특성을 결정짓는 것.
  • 행동 : Method 메소드는 어떤 값을 주고 결과값을 돌려받는 것. void - 메소드의 결과 값이 없을 때 사용하는 예약어
= 은 무엇인가요?

변수에 어떤 값을 할당 할 때 쓰는 연산자.

자바에서는 문장의 끝을 나타낼 때 “;”을 사용한다.

2. Hello Basic Java

자바는 대소문자를 중요하게 구분하는 언어.

컴파일이 뭐예요?

텍스트 파일을 작성한 것을 JVM이 실행가능한 파일로 변환하는 것. 자바 프로그램 자체적으로는 텍스트로 된 파일을 실행 할 수 없기때문에, “.java”라는 확장자의 파일을 컴파일하면 “.class” 파일로 변환한 후 실행함.

main()?

java명령으로 프로그램을 실행하면 기본적으로 가장 처음 실행되는 함수.

  • Public static void main(String[] args) {}
주석?

컴파일은 되지 않으면서, 작업에 대한 내용 공유나 히스토리 공유를 위해 남기는 부가 설명.

  • // - 한줄 주석
  • /* - 블록 주석
  • /** - 문서용 주석

3. 객체는 무엇인가요?

자바는 객체 지향 언어.

클래스 vs 객체

클래스 : 사물을 상태와 행동으로 정의한 명세 ex) 차

객체 : 실제 사물 ex) 우니의 차, 크레용의 차. - 생성자를 통해 생성

public class Person{ // class
  private String name;
  private int age;
  
  public void speak(){
    Systems.out.println("my name is" + name);
  }
}

public static void main(String[] args) {
  Person wooni = new Person(); // wooni is instance.
  wooni.speack();
}

4. 정보를 담는 공간

변수 : 값이 변하는 수. 내용을 어디에 담기 위한 공간을 말함.

지역 변수

{ } 영역 범위 내에서의 공유하는 변수.

매개 변수

함수의 호출을 할때 넘겨주는 변수.

인스턴스 변수

클래스 안에 선언된 변수(클래스 상태)

클래스 변수

static이라는 변수로 선언되어 클래스 객체들이 공유하는 변수

public class Person{
	private static String name; // class
  private int age; // instance
  
  public void speack(String sentence// parameter) {
    boolean louder; // local
  }
}
자바에는 기본 자료형과 참조 자료형이 있다.

기본자료형 : Bsil FD - Byte, Short, Int, Long, Float, Double, Boolean, char

new 연산자를 통해 객체를 초기화 하면 참조 자료형이다. 단 하나 “String”을 빼고.

5. 계산을 해볼까요?

대입 연산자 : =

더하기, 빼기, 곱하기, 나누기, 나머지 연산자 : +,-,*,/,% :

단항 연산자 : +,-,++,—,!

  • ++, —가 변수의 앞과 뒤에서의 차이 - 해당 줄을 실행하기 전에 값을 계산할지 아님 줄을 실행 한 후 값을 계산할지.
public void calculate() {
  int a = 1;
  Systems.out.println(a++); // 1
  Systems.out.println(++a); // 3
}

등가 비교 연산자 : ==,!=

  • 기본자료형은 같은 타입형끼리만 비교가 가능, 참조 자료형의 경우 주소값이 같은지 확인함.

대소 비교 연산자 : >=, <=, <, >

논리 연산자 : “&&, ||, &,
  • “&&,   “는 계산의 결과를 좌에서 우로 읽으며 하나라도 조건을 충족하면 이후를 보지 않지만, &와 는 모두 계산을 한 후 결과를 리턴함.
int number = 0;
boolean isOdd = number > 0 && number % 2 == 0;

삼항 연산자 : ? - (조건) ? 참 값 : 거짓 값

형변환 : 변수의 자료형을 변경하고 싶을 때 괄호로 묶어서 사용. ex) long a; a = (int) a; -> boolean / 기본->참조 & 참조->기본은 절대 형변환이 되지 않음.

6. 조건과 반복

조건 : If, If and Else, If and Else and If else
  • if : 조건문의 예약어
  • (조건) : boolean 결과 타입의 조건.
  • { 조건이 참일때의 처리 문장 }
  • else if (조건) : 두번째 조건
  • { 두번째 조건이 참일때의 처리문장 }
  • else : 모든 조건에 해당하지 않을 때
  • { 디폴트 처리 문장}
int number = 2;
if (number % 2 == 0) {
  Systems.out.println("This is even");
} else if(number % 2 == 1){
  Systems.out.println("This is odd");
} else {
  Systems.out.println("This is not a number");
}
타입별로 나누고 싶을 때 : Swith case
  • switch : 예약어

  • (비교대상변수) : Enum을 비롯하여, long을 제외한 정수형과 몇몇 특별한 자료형만 들어갈 수 있음.

  • case: 예약어

  • break: 해당 실행 영역을 빠져 나가고 싶을 때 사용

    -> case이후 해당 break를 사용하지 않으면, 해당 조건 이외의 영역들도 실행이 될 수 있음.

  • default: 조건문의 가장 디폴트 처리를 위한 예약어.

    -> 중간에 적게되면 원치 않은 결과를 볼 수 있기때문에 항상 case를 다 적은 후 마지막이 적을 것.

int number = 2;
switch(num % 2){
  case 0:
    Systems.out.println("This is even");
    break;
  case 1:
    Systems.out.println("This is odd");
    break;
  default:
    Systems.out.println("This is not a number");
    break;
}
반복문 : While and Do While

While은 0~반복 횟수 만큼, Do while은 최소 1~반복횟수 만큼 실행항.

  • while : 반복을 위한 예약어
  • (조건) : boolean 결과 타입의 조건.
  • { 처리문장} : 처리 문장.
int i = 1, sum = 0;
while(i <= 10){
	sum += i;
  i++;
}
Systems.out.println(sum); // 55
  • Do : 최소 1번의 실행을 위한 예약어
  • { 처리문장 } : 실행 문장
  • while(조건); : 반복의 조건을 정의, 반드시 세미콜론을 적을 것.
int i = 1, sum = 0;
Do {
	sum += i;
	i++;
} while(i <= 10);
Systems.out.println(sum); // 55
가장 확실한 반복문 : For
  • For : for문을 위한 예약어
  • int i = 1 : 변수 초기화 부분 - for문에서 한 번 실행
  • i < 5 : 반복을 위한 조건문
  • i++ : 변수의 조건 반복을 위해 사용하는 인덱스의 증가 영역
  • { 처리 문장 } : 반복 처리 될 문장.
int sum = 0;
for(int i = 0; i< 10; i++) {
	sum += i;
}
Systems.out.println(sum); // 55

7. 배열이란

한 변수에 여러개의 값을 넣을 수 있는 것을 배열이라고함.

자료구조는 무엇인가요?

데이터를 저장하기 위한 구조. ex) 배열, 리스트, Queue, Stack등

배열을 선언하기 위한 방법

  • []를 통해 배열을 선언함 -> 타입과 변수명 사이 또는 변수명 끝.
  • {}를 통해 배열 초기화 후 선언. -> 절대 변경되지 않는 값을 선언하며, 각 값들은 공백이 없는 “,”로 이어짐.

배열의 위치는 1이 아닌 0부터 시작한다!!

ArrayIndexOutOfException

배열의 인덱스가 벗어난 범위의 값을 참조 하려고 하거나 그 인덱스의 값을 초기화 하려고 할때 발생하는 익셉션

모든 참조자료형은 new를 통해서 초기화함

배열을 출력하면?

[L : 해당 객체가 배열이라는 뜻

S : 해당 배열이 스트링이라는 뜻, Long은 J, Boolean은 Z 나머지는 자신의 가장 첫번째 캐릭터 값

@해시코드 값 : 배열의 주소 해시코드 값

2차원 배열

int[] a[] 형식의 2차원 배열.

배열의 1차 부분만 초기화 하고 2차 부분은 초기화 하지 않고 선언이 가능 ex) int[1] a[]

하지만 2차 배열 부분에 접근하려 고할때 초기화 필요. ex) a[0] = int[10]

또다른 For문의 형태

Index가 필요 없이 값 자체에만 접근을 하려고 하는 경우는

for(타입 이름 임시변수명 : 반복대상 객체)의 for문을 통해 반복이 가능함.

int[] months = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
for (int a : months) {
	Systems.out.pringln(a);
}
배열은 선언 시에 크기가 고정되어야 하기때문에 이런한 유동적인 크기의 객체의 배열을 위해 Collection이 존재함.

8. 참조 데이터 자료형

기본 자료형 8가지를 제외한 나머지 자료형을 참조 자료형 이라고함.

new를 통해서만 객체를 생성할 수 있음.

생성자는 클래스 이름과 메소드의 이름이 똑같고 리턴타입이 존재 하지 않으며, 메소드의 최상단에 위치.

기본 생성자는 생성자를 하나도 선언하지 않은 경우에 자동으로 생성됨. 즉, 생성자를 하나라도 선언한 경우에는 기본 생성자는 생성되지 않기 때문에 수동으로 생성이 필요.

This는 매개변수와 객체 변수의 이름이 같을 때 객체 변수를 지정하려고 사용한다.

메소드가 종료되는 조건

메소드가 끝나거나, return을 만나거나, 예외가 발생하거나

static메소드와 일반 메소드의 차이.

static메소드는 객체를 생성하지 않고, 클래스 명으로만으로도 접근이 가능. 또한 static메소드에서는 static 필드만 접근이 가능함.

public class StaticTextClass{
  private static String status = "INITIAL";
  
  private static String getStatus(){
    return this.status;
  }
}
static block

객체를 선언하는 부분전에 클래스에 변수등을 초기화 하기위해 딱 한번만 호출이 되는 함수.

pass by Value or pass by Referenct

기본 자료형과 참조 자료형은 매개변수로 넘어갈때 Pass by Value로 넘어감.

참조 자료형 안에 있는 변수들은 Pass by Reference로 넘어감.

[]대신 …

한 타입의 변수를 한 번에 여러개 받고 싶을때 [] 대신 … 사용 가능.

대신 이 타입은 메소드의 가장 끝에 위치해야하며, 하나의 메소드에서 한 번만 사용이 가능.

9. 패키지와 접근제어자

패키지를 사용하지 않는다면? 클래스가 중복되거나 클래스가 어떤일을하는지 혼동될 수 있음.

”/”로 각 패키지를 구분, 윈도우는 “\“로도 컴파일이 가능함.

패키지의 특징
  • 소스의 가장 첫 줄에 한줄로만 있어야 함.
  • 예약어는 사용이 불가.
  • 패키지의 이름과 폴더의 이름이 같아야함.
  • 모두 소문자 여야함.

다른 패키지에 접근하고 싶다면? import, import static

해당 패키지 하위의 모든 패키지에 접근하고 싶다면? *

접근제어자의 범위
  • public : 누구나 접근
  • protected: 상속 받은 클래스에서 접근
  • package-private: 같은 패키지 내에서 접근 - default
  • private: 해당 클래스만 접근

10. 상속

Extends

부모의 클래스를 상속받겠다는 예약어이며, 부모 클래스 내의 package-private 과 private 접근제어 이외의 나머지 모든 변수와 메소드에 접근이 가능해짐.

  • 자식 클래스의 객체를 생성하면 자동으로 부모의 매개변수가 없는 생성자가 호출 됨. 부모의 클래스의 매개변수가 없는 생성자가 없다면 super()를 통해서 부모의 생성자를 호출 가능.
  • 1개의 클래스만 상속이 가능함.
메소드 Overriding

자식 클래스에서 부모 클래스의 메소드의 리턴타입, 시그니처와 이름이 같은 메소드를 재 정의 하는 것.

접근제어자는 확대는 가능하지만 축소는 가능하지 않음.

Overriding vs Overloading

메소드를 덮어쓰느냐 확장하느냐.

형변환

자식 클래스 -> 부모 클래스로의 형변환 : 명시적으로 적어줌

부모 클래스-> 자식 클래스로의 형변환: 불가. 하지만 부모 클래스의 변수가 자식 클래스의 객체를 가지고 있다면, 명시적으로 적어줌으로 써 가능.

클래스의 타입이 무엇인지 체크하고 싶다면? Instance of
다형성(Polymorphism)

부모 클래스로부터 상속받은 자식 클래스들의 객체들은 부모 클래스로 형변환이 가능하고, 부모 클래스로 부터 상속받은 공통의 메소드들을 오버라이드 구현이 가능함.

즉, 부모 클래스로 보여도 선언이 되었던 객체들 마다 다른 메소드의 수행이 가능함.

public class Parent{
  public void printObject();
}

public class ChildTest1 extends Parent{
	public void printObject(){
    Systems.out.println("child 1");
  }
}


public class ChildTest2 extends Parent{
	public void printObject(){
    Systems.out.println("child 2");
  }
}

public static final void main(String[] args) {
  Parent a = new ChildTest1();
  a.printObject(); // child 1 print
  
  a = new ChildTest2();
  a. printObject(); // child 2 print
}

11. java.lang.Object

모든 클래스의 부모.

즉 컴파일 시에 모든 클래스는 자동으로 “extends Object”가 추가됨.

이중 상속이 안된다고 했잖아요?

단계별 상속은 가능. 즉 A 클래스는 B클래스를 상속받고, B클래스는 C클래스를 상속받는 것이라면, A는 B와 C를 상속받은 클래스가 됨.

Public class A extends B {
}

public class B extends C {
}

Object 클래스의 메소드들

  • toString() : 클래스 객체의 정보를 문자열로 내보냄. 오버라이드를 통해서 클래스의 문자열 출력을 지정할 수 있음.
  • equals(): 클래스가 객체 같은지를 비교할 때 호출.
  • clone(): 클래스 객체가 복사되어질 때.
  • hashcode(): 클래스의 객체가 가지고 있는 주소값이 리턴됨.
  • getClass(): 클래스 타입을 가져옴.
  • finalize(): 객체가 메모리에서 할당이 끝날때, GC가 호출될 때 수행.
객체의 비교

기본 자료형의 값을 비교할때는 ==를 사용했음.

하지만 참조자료형의 경우 ==로 비교를 하게되면, 객체의 주소값을 비교하게 됨으로 equals()메소드를 통해서 객체의 같음을 비교해야함.

12. Abstract Class와 Enum

interface vs abstract

interface는 메소드의 명세를 정의하기 위한 것으로 메소드의 구현이 전혀 없는 메소드의 선언만을 가지고 있음.

interface는 클래스가 아니기 때문에 extends가 아니라 implements로 구현을 해야함.

class와는 다르게 여러 인터페이스의 구현이 가능함.

public interfact Itest{
	public void test();
}

abstract는 메소드 중에 하나라도 선언이 되지 않고 abstract method가 존재한다면 abstract클래스 여야함.

abstrac클래스는 선언부가 있는 메소드와 선언부가 없는 메소드의 공존이 가능함.

static, final 메소드의 선언도 가능함.

public abstract class Test{
  public abstract boolean mandatoryOverride(); // 하위 클래스에서 선언이 필요함.
	public void printTest(){
    Systems.out.println("test");
  }
}
final
  • Class: 상속이 불가한 클래스
  • Method: 오버라이딩이 불가한 메소드
  • 변수: 값의 초기화 이후 변경이 불가한 변수

  • 참조 자료형의 객체가 final로 선언이 된경우에는, 객체 자체를 변경할 수는 없지만 안쪽의 인스턴스 변수나 클래스 변수가 final이 아니라면 접근이 가능.
Enum

고정된 값(상수)의 집합.

부모 클래스는 java.lang.Enum

  • compareTo: enum타입과 순서를 리턴
  • getDeclaringClass(): enum이 선언된 클래스를 반환.
  • name(): enum의 값을 반환
  • Ordinal(): enum의 선언된 순서를 반환
  • valueOf(): static 메소드로써, enum의 값을 매칭해서 반환.

13. Nested, Inner and Anonymous Class

Static Nested

한 곳에서 선언되는 클래스를 논리적으로 묶어서 처리하고 싶을 때.

클래스 내부에 선언된 static 클래스.

선언은 외부 클래스.Static Nested클래스의 이름으로 new 로 생성. ex) A안에 B가 스태틱 네스티드 클래스인 경우 : new A.B()

static 변수에만 접근이 가능.

class A {
	static class B {
	}
}
Inner

안쪽으로 클래스를 감추어 캡슐화를 하고 싶을 때.

클래스 안에 static이 없는 또다른 클래스가 선언되어 있는 케이스.

선언은 외부 클래스의 객체.new Inner 클래스의 이름으로 생성. ex) A안에 B가 내부 클래스인 경우: A a= new a(); a.new B()

모든 변수 접근 가능.

class A {
	class B{
	}
}
Anonymous

클래스의 객체가 많이 선언될 수록, 메모리를 많이 사용하기 때문에 해당 영역 내에서만 해당 객체를 명확히 사용하고 참조를 끊고 싶을 때. 즉, 재사용이 필요 없는 경우 가장 많이 사용.

interface를 통한 객체의 선언만 있고, 그것을 구현한 클래스가 없지만 메소드 내에서 동적으로 선언해서 사용하는 클래스.

Button.setListener(new EventListener() {

	public void onClick() {}

})

모든 변수 접근 가능.

14. Exception

try - catch - finally

메소드 내부가 실행되면서, 예상치 못한 익셉션이 발생했을 때 해당 에러를 처리하기 위한 블럭.

catch에서는 다양한 checkedException이나 Runtime Exception을 처리할 수 있음.

catch에서는 여러 익셉션을 잡을 수 있으며, 해당 익셉션들의 포함 범위는 아래로 갈 수록 더 넓은 범위여야함.

finally 에러가 발생하든 안하든 무조건 호출되는 영역 ex) 파일 처리가 끝낸 후 파일의 객체를 닫을 때 사용.

try{
  String nullText = null;
  nullText.equals('a');
} catch(NullPointerException e){
  Systems.out.println(e.getMessage()); // print here.
} catch(Exception e){
  Systems.out.println(e.getMessage());
}
Error의 종류
  • Error: 자바 프로그램 밖에서의 예외. ex) 네트워크가 단전되었거나 idc에서 장애가 발생하거나 등.
  • runtime exception: 예외가 발생할 것을 미리 감지하지 못했을 때 발생. 그 중 실행시에 해당 예외의 발생을 인지할 수 있는 익셉션들.

  • checked exception : Exception을 상속받은 클래스들로 컴파일 시에 확인되는 익셉션.
throw vs throws

메소드 내에서 익셉션을 발생하고 싶을 때 : throw new Exception()

메소드의 선언에서 익셉션이 발생될 것을 미리 선언하고 싶을 때: public void exceptionTest() throws Exception {}

thorws가 포함된 메소드를 호출하는 쪽에서는 try - catch로 메소드의 익셉션 발생 케이스를 핸들링 하는 것이 좋음.

15. Anotation

  • @Override: 부모 객체로 부터 상속받은 메소드를 오버라이드 한 경우
  • @Deprecated: 메소드가 새롭게 선언되어 사용하지 않음을 명시하고 싶은 경우
  • @SuppressWarnings: 미리 인지하고 있는 컴파일러의 에러의 경우 워닝으로 처리하고 싶은 경우.
나만의 anotation을 만들어 보고 싶다면?
  • @Target: 어노테이션을 어느 영역에 적용할 지. ex) METHOD or TYPE(Class, interface and Enum)
  • @Retention: 어노테이션의 정보 유지를 얼마나 할지.
  • @Documented: 문서를 정의할 때.
  • @Ingerited: 부모의 어노테이션을 자식의 클래스에게도 물려 줄지.

어노 테이션의 값을 확인해 보고싶다면, 해당 메소드인 경우에는 클래스로부터 메소드의 명세를 꺼내 어노테이션에 접근이 가능.

어노테이션 역시 상속이 불가함.

자바의 Garbage Collector

JVM의 경우 C언어 처럼 명시적으로 메모리의 영역 할당을 해제하지 않음.

자바는 재귀 함수나 메소드 내에서 메소드를 호출하는 순차적인 호출인 경우에는 stack에 호출순서를 Heap에 해당 변수와 메소드들을 할당.

클래스나 기타 다른 객체들의 경우에는 heap에 할당하게 됨.

heap은 young + old + perm으로 구성이 되어있음.

변수나 객체를 처음 생성하게 되면 young의 eden영역에 할당이 되고, 이후 참조가 끊기거나 하면서 gc에 의해 삭제됨.

하지만 계속 참조가 유지되는 경우 Survivor영역으로 이동이되고, 해당 survivor이 가득 차게 되면 Young(Minor) GC가 발생하게 됨.

Young영역에서 계속해서 참조가 유지되는 경우는 old영역으로 이동하게 되고, 이 old영역이 가득차게 되면 Major(Full) GC가 발생.

참조

자바의 신 VOL.1 - 이 상민 지음