FIF's 코딩팩토리

자바 공부중 정리(1) 본문

Back-End/Java(자바)

자바 공부중 정리(1)

FIF 2019. 6. 17. 16:51
반응형

클래스

new는 클래스로 부터 객체 생성하는 연산자.

new 연산자가 생성한 객체는 heap영역에 저장되는 동시에 이 객체의 주소가 리턴된다. 

new 연산자로 객체 생성 -> 객체의 주소를 변수에 저장 -> 변수가 객체를 참조

 

클래스의 구성멤버

클래스에는 객체가 가져야 할 구성 멤버가 선언된다.

필드:객체의 고유 데이터, 상태 정보, 부품 객체를 저장하는 곳

 

생성자:클래스로부터 객체를 생성할 때 호출되어 객체의 초기화 담당

new연산자의 생성자 실행 -> heap영역에 객체 생성 -> 객체의 주소 리턴 -> 주소가 클래스 타입 변수에 저장 됨

생성자를 명시적으로 선언하는 이유는 객체를 다양하게 초기화 하기 위해서.

메소드:객체의 동작, 객체 간의 데이터 전달 수단

 

필드와 변수는 닮앗지만, 필드를 변수라 하진 않음.

 

변수는 생성자와 메소드 내에서만 사용되고, 생성자와 메소드가 실행 종료되면

자동 소멸함.

 

필드는 객체가 소멸할 때 사라짐.

 

this.필드 : this라는 참조 변수로 필드를 사용

 

메소드 오버로딩 : 클래스 내에 같은 이름의 메소드를 여러개 선언

(오버로딩의 사전적 의미 : 많이 싣는다)

조건 : 매개 변수 타입, 개수, 순서중 하나가 달라야함

 

왜필요해? 매개값을 다양하게 받아 처리하기 위해

 

인터페이스를 상속받은 클래스는 반드시 인터페이스에 있는 메소드를 모두 구현해야 하지만,

(인터페이스안에 추상메소드만가능)

추상클래스를 상속받은 클래스는 추상메소드만 구현하고 일반메소드는 사용하지 않아도 문제가 없다.

(추상클래스 안에 일반메소드+추상메소드 가능)

 

 

상속

개념 : 어떤 객체가 있을 때 그 객체의 필드(변수)와 메소드를 다른 객체가 물려 받을 수 있는 기능을

상속이라 한다.

언어개발자 입장에서 기존의 객체를 그대로 유지하면서 어떤 기능을 추가하는 방법이 없을까라는

고민에서 상속의 개념이 나왔다.

기존의 객체는 기능을 물려준다는 의미에서 부모 객체가 되고,

새로운 객체는 기존 객체의 기능을 물려받는 의미에서 자식 객체가 된다.

 

상속 키워드 -> extends

class Calculator{  }; //이 클래스는 그대로 유지한다.

 class SubstractionableCalculator extends Calculator{  }; //Calculator기능을 상속받겠다.

 

 class Main {

 

    public static void main(String[] args) {

        SubstractionableCalculator c1 = new SubstractionableCalculator();

        c1.setOprands(10, 20);

        c1.sum();

        c1.avg();

        c1.substract(); //이 메소드가 하위클래스에서 새로 추가된 메소드

    }

}

SubstractionableCalculator클래스를 c1으로 인스턴스화 시킨다.

 

코드의 중복제거(재활용성 높다.)

유지보수가 편리하다.

상위클래스에 코드가 있기때문에 가독성 증가.

 

----------------------------------상속과 생성자-----------------------------------

public class ConstructorDemo{    
           //생성자가 선언부가 없으므로 JVM은 자동으로 default생성자를 만듬
           public static void main(String[] args){
                      ConstructorDemo c = new ConstructorDemo();//메인 메소드에서 자기자신을 인스턴스화 시킬수도있다.
                      //이게 가능한건 ConstructorDemo메소드에 해당하는 생성자를 JVM이 자동으로 만들었기 때문에.
           }
}
//vs

public class ConstructorDemo{
           public ConstructorDemo(){}//기본생성자 만들어주면 해결 됨
           public ConstructorDemo(int param1){}//매개변수가 있는 생성자(default생성자가 아님)
           public static void main(String[] args){
                      ConstructorDemo c = new ConstructorDemo();//이때 클래스를 인스턴스화 시키면 에러발생.
           }

}

 

 

           super(left, right); //부모클래스의 생성자!

 

하위클래스의 초기화 코드는 무조건 슈퍼클래스를 호출한 다음에 나타나야 함.

하위클래스가 인스턴스화 된다는 말은 상위클래스가 이미 인스턴스화 돼었다라는 말이기 때문.

다시말해서 상위클래스의 초기화가 다 끝나야만 하위클래스의 초기화가 진행된다.

 

오버라이딩

재정의

부모가 가지고 있는 메소드를 물려받긴 했지만,

그 메소드를 그대로 쓰지 않고 자식 클래스의 상황에 맞게 재정의해서 씀

 

똑같은 이름의 메소드를 부모클래스도 가지고 있고 자식클래스도 가지고 있을때,

자식 메소드에서 재정의 해주면 부모클래스 메소드는 무시됨.

 

오버라이딩의 조건

 

상위클래스에서 void avg( ){ };

하위클래스에서 int avg( ){ };

error: incompatible types: void cannot be converted to int

void int는 호환되지 않는다.

 

부모클래스 메소드와 자식클래스 메소드가 같아야 할점

1) 메소드의 이름

2) 메소드 매개변수의 숫자와 데이터 타입 그리고 순서

3) 메소드 리턴 타입

public int avg(){

           return super.avg(); //해버리면, 코드중복피하고 상위클래스에서 수정해도 안고쳐도 됨.

}

자식메소드가 부모메소드를 호출하기 위해 사용하는 키워드 super()

->하위클래스에서 기능 추가 가능

-------------------------오버로딩---------------------

public void setOprands(int left, int right){

        System.out.println("setOprands(int left, int right)");

        this.left = left;

        this.right = right;

    }

 

    public void setOprands(int left, int right, int third){

        System.out.println("setOprands(int left, int right, int third)");

        this.left = left;

        this.right = right;

        this.third = third;
        c1.setOprands(10, 20);
 		c1.setOprands(10, 20, 30);

    }

 

 

 

매개변수의 개수에 따라 같은 이름의, 서로 다른 메소드를 호출한다.

 

이름은 같지만 시그니처가 다른 메소드를 중복으로 선언할 수 있는 방법을 메소드 오버로딩

public void setOprands(int left, int right){

        this.left = left;

        this.right = right;

    }

 

    public void setOprands(int left, int right, int third){

        this.setOprands(left,right); //중복되는거 이걸로 해결. 오 이게돼?

        this.third = third;

    }

 

오버로딩의 규칙

메소드의 이름과 리턴타입은 같아야 하고 매개변수 개수는 달라야 한다.

매개변수의 이름은 같거나 달라도 상관없음.

 

 

오버라이딩 vs 오버로딩

 

오버로딩(Overloading) : 같은 이름의 메소드를 여러 개 가지면서 매개변수의 유형과 개수가 다르도록 하는 기술

 

오버라이딩(Overriding) : 상위 클래스가 가지고 있는 메소드를 하위 클래스가 재정의 해서 사용한다.

 

 

추상메소드

상속을 강제하는 일종의 규제.

abstract 클래스나 메소드를 사용하기 위해서는 반드시 상속해서 사용하도록 강제.

 

 

public abstract int b ( ); //추상메소드는 본체가 없다.

 

메소드 중에 하나라도 추상메소드 이면 클래스도 추상클래스가 된다.

 

부모 클래스에는 메소드의 시그니처만 정의해놓고 그 메소드의 실제 동작 방법은 이 메소드를

상속 받은 하위 클래스의 책임으로 위임.

 

상위클래스(추상클래스) 에는 공통적으로 사용되는 로직을 구현하고,

이를 상속받은 하위클래스에서는 용도에 따라 달라지는 구현을 사용자가 직접 하도록 규제함

 

-------------------------------------interface-------------------------

어떤 객체(클래스)가 있고, 객체가 특정한 인터페이스를 사용한다면, 그 객체는 반드시 인터페이스의

메소드들을 모두 구현해야 한다.

Interface I{

    public void z();

}

class A implements I{      //클래스 A는 Interface I를 구현한다.

           public void z(){}

}

 

추상클래스 vs 인터페이스

추상클래스는 기존의 클래스에서 공통된 부분을 추상화하여 상속하는 클래스에게 구현을 강제화

메소드의 동작을 구현하는 자식클래스로 책임을 위임, 공유의 목적이 강함

 

인터페이스는 클래스가 아니고, 구현하는 모든 클래스에 대해 특정한 메소드가 반드시 존재하도록 강제 함.

다중 구현 가능

 

인터페이스는 클래스와 별도로 일련의 연관된 메서드를 정의하고,

추상 클래스는 메서드를 선언하지만 모든 메서드를 선언하지 않은 불완전하게 정의된 클래스

 

추상 클래스는 일반적으로 베이스 클래스로 상속해서 더 구체적인 클래스를 만들 때 쓰기 좋다.

인터페이스는 서로 관련이 없는 클래스에서 공통적으로 사용하는 방식이 필요하지만 기능을 각각 구현할 경우 좋다.

 

추상 클래스는 상속 받아서 기능 확장이 목적,

인터페이스는 구현 객체의 같은 동작을 보장하기 위한 목적(뼈대)

 

예외처리

예외는 무엇이고 오류는 무엇인가?

예외

프로그램을 만든 프로그래머가 상정한 정상적인 처리에서 벗어나는 경우에 이를 처리하기 위한 '방법'

 

+e.getMessage() 호출하면 by zero라고 나옴.

 

오류가 날수 있는 구문을 try{}에 넣고 에러가 발생하면 try{}는 중단되고, catch(){}구문이 실행된다.

 

JVM catch(){}를 자동으로 실행한다.

try{

           예외의 발생이 예상되는 로직

} catch(예외클래스 인스턴스){ //마치 메소드

           예외가 발생했을때 실행되는 로직

}

 

 

e.getMessage() : 오류에 대한 기본적인 내용 출력

e.toString() : java.lang.ArthmeticException:/ by zero 와 같이 예외정보 제공

e.printStackTrace() : 내부적으로 예외 결과 화면에 리턴. 가장 자세한 예외정보 제공

 

ArrayIndexOutofBoundsException : 배열의 인덱스 값이 가질 수 있는 범위를 초과했다.

ArithmeticException : 주로 어떤 수를 0으로 나눴을때 발생하는 예외

 

여러가지의 예외처리를 하려면 if~else문처럼

catch문을 여러개 써서 분기할 수 있다.

catch(ArrayIndexOutOfBoundsException e){

            System.out.println("ArrayIndexOutOfBoundsException");

        } catch(ArithmeticException e){

            System.out.println("ArithmeticException");

        } catch(Exception e){

            System.out.println("Exception");

        }

 

Exception e 가 맨 위에 있으면 그 아래 ~~Exception들은 실행이 안된다.

(모든 Exception을 포괄해서)

try{

           예외의 발생이 예상되는 로직

} catch(예외클래스 인스턴스){ //마치 메소드

           예외가 발생했을때 실행되는 로직

} finally{

           예외여부와 관계없이 무조건 실행

}

 

예를들어

db app이랑 연결시 finally close()를 해줘야함(db 10개 밖에 연결 안되는데, 안끈어주면 망함)

 

예를들어

Unhandled exception type FileNotFoundException

파일이 없을때 나타날 수 있는 Exception을 다루지 않고 있다.

Unhandled exception type IOException

Input, Output이 없을때 나타날 수 있는 Exception을 다루지 않고 있다.

 

FileReader

public FileReader(File file) //FileReader라는 생성자

           throws FileNotFoundException

 

Creates a new FileReader, given the Fileto read from.

Parameters:file - the File to read fromThrows:FileNotFoundException -

if the file does not exist,is a directory rather than a regular file,

or for some other reason cannot be opened forreading.

 

Throws:

FileNotFoundException - if the file does not exist,is a directory rather than a regular file,

or for some other reason cannot be opened forreading.

 

throws는 자기가 예외를 처리하는게 아니라, 다른 사용자한테 던지는 것임.

-------------------------------------------------------------------------------

getCause()

Returns the cause of this throwable or null if the cause is nonexistent or unknown.

 

Throwable getCause() - 예외가 발생한 근본적인 원인 예외를 반환합니다. 원인 객체가 없는 경우 null을 반환합니다.

 

쓰레드

동시성(Concurrency) : 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아 가며 실행

하는 성질(번갈아 실행 하는것이 워낙빨라서 병렬 처럼 보임)

 

병렬성(Parallelism) : 멀티 작업을 위해 멀티 코어에서 개별 스레드를 동시에 실행하는 성질.

 

----------------------------------------------------------------------------------------------

스레드 스케줄링 : 스레드의 개수가 코어의 개수보다 많을경우, 스레드를 어떤 순서에 의해

동시성으로 실행 시킬 것인가.

 

우선순위(Priority) : 우선순위가 높은 스레드가 실행 상태를 더 많이 가지도록 스케줄링

 

순환 할당(Round-Robin) : 시간 할당량(Time-Slice)을 정해서 하나의 스레드를 정해진 시간만큼

실행하고 다시 다른 스레드를 시간 할당량 만큼 실행

 

임계영역(Critical Section) : 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수있는

코드 영역

 

자바는 임계영역 지정을 위해 동기화(Synchronized) 메소드와 동기화 블록을 사용.

스레드가 객체 내부의 동기화 메소드 또는 블록에 들어가면, 즉시 객체에 잠금을 걸어

다른 스레드가 임계 영역 코드를 실행하지 못하게 함.

 

동기화 메소드보다 동기화 블록을 사용하면, 다른 스레드들이 좀더 빠르게 준비상태에

접어들 수있음(블록은 지정한 몇줄이므로 전체 메소드가 동기화 될 때 까지 기다릴 필요없다.)

 

제네릭

제네릭(Generic)은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법.

class Person<T>{

     public T info;

}

Person<String> p1 = new Person<String>( );//info라는 필드가 스트링이라는 데이터 타입을 갖는 클래스를 생성

 

Person<StringBuilder> p2 = new Person<StringBuilder>( );//T를 인스턴스화 할때 String 으로 데이터 타입을 지정 해줌

제네릭을 사용하는 이유

타입이 안전하지 않음.(자바상에선 허용하지 않음)

컴파일 과정에서 개발자의 실수가 나타나야 컴파일언어의 혜택을 누릴 수 있다.

 

제네릭을 사용하면 컴파일 시에 미리 타입이 정해지므로, 타입 검사나 타입 변환과 같은 번거로운 작업을

생략할 수 있게 됩니다.

-----------------------------

제네릭에는 참조 데이터 타입만 올 수 있다.

기본 데이터 타입을 사용하기 위해선 Wrapper클래스 써야한다.(기본 데이터 타입은 객체가 아니기 때문에!)

 

Wrapper가 기본 데이터 타입을 객체로 포장한다.

int에 대한 Wrapper Integer -> intValue() 하면 원시데이터 타입 호출 가능

double에 대한 Wrapper Double

 

결론 : 기본 데이터 타입도 Wrapper클래스를 사용해 우회해서 쓸 수 있다.

 

class Person<T extends Info>{ //제네릭에 아무 데이터 타입이나 못오도록 상속받을 수 있다.(추상클래스)

   public T info;

   Person(T info) {this.info = info}

}

 

interface Info{

   int getLevel();

}

 

class EmployeeInfo implements Info{ //인터페이스로 구현할 수 도 있다.

           public int rank;

           EmployeeInfo(int rank){this.rank = rank;}

           public int getLevel(){

                      return this.rank;

           }

}

 

 

Object클래스

class o{} , class o extends Object{} 는 같다.

 

모든 클래스들의 공통 조상은 Object클래스다.

 

toString() 클래스는 문자화 시켜준다.

------------------------------------

equal는 객체와 객체를 비교할때 쓴다.

원시 데이터를 비교할땐 ==를 쓴다.

class Student {
           String name;
           Student(String name) {
                      this.name = name;
           }
           @Override

           public boolean equals(Object obj) { //데이터 타입이 object ,  Object obj = s2;//자식이 부모행세 하는건 가능
                                               //부모가 자식행세는 불가능
                  Student _obj = (Student) obj;//obj를 사용하여 Student타입에접근 하려면 obj->Student 명시적 형변환 해야함
                  return name == _obj.name;
           }
}
public class ThreadA {
           public static void main(String[] args) {
                      Student s1 = new Student("egoing");
                      Student s2 = new Student("egoing");
                      System.out.println(s1 == s2);
                      System.out.println(s1.equals(s2)); //s2는 Student형 인데, 부모가 Object형이다! Object obj = s2;
           }
}

equals() 메소드를 직접 구현 해야 하는 상황이라면 hashCode() 메소드도 직접 구현 해야한다.

 

finalize()

객체가 소멸될 때 호출되기로 약속한 메소드.

 

가비지 컬렉션(garbage collection)

인스턴스를 만드는 것은 컴퓨터의 메모리()을 사용하는것.

휘발성임.

프로그램은 램에 올라간 상태에서 실행 된다. 하지만 용량이 적고 가격이 비싸다.

 

자바에서는 램 관리를 자동화 시켰다(가비지컬렉션)

변수사용이 없다면 jvm은 정기적 순찰을 돌면서 안쓰는 변수(데이터)를 삭제 한다.

 

---------------------------------------------

가비지 컬렉션 과정 - Generational Garbage Collection(이하 GC)

stop-the-world : GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것

 

컬렉션프레임워크

컬렉션즈프레임워크란?

다른 말로는 컨테이너라고 함. , 값을 담는 그릇.

그 값의 성격에 따라 컨테이너의 성격이 조금씩 달라짐.

//기존 배열 문법  

String[] arrayObj = new String[2];

        arrayObj[0] = "one";

        arrayObj[1] = "two";

        // arrayObj[2] = "three"; 오류가 발생한다.

        for(int i=0; i<arrayObj.length; i++){

            System.out.println(arrayObj[i]);

        }

 

//ArrayList문법

   ArrayList al = new ArrayList();//여기 다르다.  ArrayList의 인자값은 모두 "Ojbect"다.

        al.add("one");//여기 다르다.

        al.add("two");

        al.add("three");

        for(int i=0; i<al.size(); i++){ //여기 다르다.

           String value = (String) al.get(i);  //al.get리턴타입은 Object이므로 String으로 가져오려면 형변환 해줘야함

            System.out.println(al.get(i));//여기 다르다. get쓰네.

        }

 

 

//generic 문법적 수단 채택

 ArrayList<String> al = new >ArrayList<String>( ); al 이라는 ArrayList에 추가되는 값이 String데이터 타입이라는 것을 제네릭을 통해 지정

        al.add("one");

        al.add("two");

        al.add("three");

        for(int i=0; i<al.size(); i++){

           String value =al.get(i); //따로 형변환 해줄필요 없.다.

            System.out.println(al.get(i));

        }

List Set의 차이점

List는 중복 허용, Set은 허용하지 않음.

 

set은 수학에서의 집합과 같은 의미로 순서가 없고 중복되지 않는다는 특성.

System.out.println(A.containsAll(B)); // false A에 대해서 B는 부분집합이 아니다.

System.out.println(A.containsAll(C)); // true A에 대해서 C는 부분집합 이다.

        //A + B

        A.addAll(B);(합집합)


        //A와 B의 교집합

        A.retainAll(B);
 

        //A - B(차집합)

        A.removeAll(B);

 

MAP KEY값을 제공하면 거기에 해당하는 VALUE값을 리턴 해줌

KEY값은 중복 X

VALUE는 중복  O

   HashMap<String, Integer> a = new HashMap<String, Integer>(); // 2개의 제너릭 KEY, VALUE

 

put MAP에서만 있음

 

Collections.sort(computers);  는 정렬하는 클래스

Collections에있는 메소드들은 static이기때문에 인스턴스 생성하지 않고 바로 호출 가능

     public int compareTo(Object o) {
        return this.serial - ((Computer)o).serial;
    }

을 이용하여 정렬(시리얼)

 

API(Application Programming Interface)

라이브러리 라고도함.

프로그램 개발에 자주 사용되는 클래스 및 인터페이스의 모음.

 

반응형
Comments