• 인터페이스는 객체 사용 설명서 (공통API의 역할)
    인터페이스의 메소드는 전부 abstract 메소드 (키워드 생략)
  • 자바7까지는 추상메소드만 선언가능했는데
    자바8에서부터는 디폴드메소드, 정적메소드도 선언가능
  • 코드수정없이 객체를 변경할 수 있다
    > 동일기능의 구현객체를 새로만들고 선언부만 변경 가능
  • 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출
  • 인터페이스의 구현클래스에서 메소드를 작성할때 더 낮은 접근제한을 지정할수없음
    (추상메소드는 디폴트로 public)
    인터페이스 설계의 핵심은 선언부를 얼마나 추상화하여 작성할 것인가...
  • 인터페이스는 다중상속 가능
  • 디폴트 메소드 필요성
    - interfaceA 를 사용하다가 추가할 기능이 생겼을때 추상메소드를 추가하면 interfaceA 구현체에 모두 추가해줘야하는데
    디폴트메소드는 추상메소드가 아니기 때문에 구현클래스에서 모두 작성해줄 필요가 없음
    - 리턴타입 앞에 default 작성
  • 인터페이스 vs 추상클래스
    접근제한자 모두 public / 접근제한자 지정 가능
    구현객체가 동일기능을 구현 / 핵심로직은 추상클래스에서 정의하고 달라지는 부분만 구현객체에서 작성
    > 나중에 디자인패턴에서 쓰임 비교해보기


1번 - 3
2번 - 4
3번 -

public class Cat implements Soundable {
  @Override
  public String sound() {
  	return "야옹";
  }
}
public class Dog implements Soundable {
  @Override
  public String sound() {
  	return "멍멍";
  }
}


4번 -

public interface DataAccessObject {
  void select();
  void insert();
  void update();
  void delete();
}
public class OracleDao implements DataAccessObject {
  public void select() {
  	sysout("OracleDB에서 검색")
  }
  public void insert() {
  	sysout("OracleDB에서 삽입")
  }
  public void update() {
  	sysout("OracleDB에서 수정")
  }
  public void delete() {
  	sysout("OracleDB에서 삭제")
  }
}
  
public class MySqlDao implements DataAccessObject {
  public void select() {
  	sysout("MySqleDB에서 검색")
  }
  public void insert() {
  	sysout("MySqleDB에서 삽입")
  }
  public void update() {
  	sysout("MySqleDB에서 수정")
  }
  public void delete() {
  	sysout("MySqleDB에서 삭제")
  }
}


5번 -

Action action = new Action() {
	public void work() {
		sysout("복사를 합니다.");
	}
};

'Language > Java' 카테고리의 다른 글

자바 커뮤니티2 - 상속  (0) 2019.05.28
자바 커뮤니티1 - Class  (0) 2019.05.22
Java 문자열 객체  (0) 2018.08.04
Java 배열 선언, 초기화  (0) 2018.08.04
Java 접근지정자 (Access Modifier)  (0) 2018.08.04

*추상클래스 개념

- 추상은 사전적 의미로 실체간의 공통되는 특성을 추출하는 것

- 실체클래스들의 공통특성을 추출해서 선언한 클래스를 추상클래스

- 추상클래스와 실체클래스는 상속관계에 있고 추상클래스의 모든 특성을 물려받음

- 추상클래스로는 직접 객체를 생성할 수 없다.

 

*추상클래스 용도

- 표준화: 실체클래스들의 공통된 필드와 메소드의 이름을 통일할 목적

(개발자간 문서설계로도 가능하지만 추상클래스로 잘 설계해놓으면 코드만 보고도 실체클래스들을 구현할 수 있다.)

- 개발시간단축: 실체클래스를 작성할 때 시간 절약

(공통적인 필드와 메소드는 추상클래스에 정의해두고 실체클래스마다 다른기능만 개발하면 개발시간을 단축시킬수있다.)

- 사내에서도 BaseBatch 라는 추상클래스가 있어서 이를 상속받아 배치를 구현하는 프로세스가 있다.

- *잘만들어진 추상클래스는 프레임워크나 오픈소스같은 곳에서 유용하게 사용되고있다.

(메인로직은 추상클래스에 정의하고 구현체에서는 각 애플리케이션 기능의 특성을 담는 구조로 개발가능)

 

*자바는 다중상속이 불가능하지만 인터페이스로 다중상속 가능

*인터페이스는 다음시간에!

 

 

[ 확인문제 ]

1 - 1

자바는 다중상속을 허용하지 않음

 

2 - 2

부모-자식 상속 관계에서 자식클래스를 자동타입변환한 부모클래스에 대해서만 강제타입변환이 가능

// 자동타입변환을 하면 부모클래스에 있는 메소드만 사용할수있는 제약이 생기기때문

 

3 - 1

final 클래스로 상속을 할수없기 때문에 부모클래스가 될수없음

 

4 - 4

protected 접근제한을 갖는 메소드는 다른 패키지의 자식클래스에서 재정의 가능

 

5

자식클래스의 생성자에서 자동으로 super(); 를 호출하는데

부모클래스에 디폴트 생성자가 없음 (매개변수생성자가 있으면 내부적으로 디폴트생성자 안생김)

이를 해결하기 위해서는 부모클래스에 디폴트생성자를 추가하거나

자식클래스에서 부모클래스의 매개변수생성자를 명시적으로 호출하면됨

 

6

Parent(String nation) call

Parent() call

Child(String name) call

Child() call

 

7

일반타이어가 굴러갑니다.

스노우타이어가 굴러갑니다.

// 자동타입변환을 해도 해당 객체로는 부모클래스의 메소드만 접근 가능

 

8 - 2

자식클래스를 자동타입변환한 부모클래스에 대해서만 강제타입변환이 가능

'Language > Java' 카테고리의 다른 글

자바 커뮤니티3 - 인터페이스  (0) 2019.06.05
자바 커뮤니티1 - Class  (0) 2019.05.22
Java 문자열 객체  (0) 2018.08.04
Java 배열 선언, 초기화  (0) 2018.08.04
Java 접근지정자 (Access Modifier)  (0) 2018.08.04

사내에서 자바 커뮤니티를 개설하여 기본 개념은 다시 공부하고 Java8의 새로운 개념, 문법을 공부해보려고한다.

교재는 팀원들과 [이것이 자바다 - 신용권의 Java 프로그래밍 정복] 으로 정하였고 나는 ch6. 클래스부터 참여하였다.

아래는 연습문제풀이 및 스터디 시간에 공유한 내용이다. (코드복붙하다가 인덴테이션이나 문법같은게 조금 깨졌..)

 

* 디폴트 생성자의 접근지정자

- 명시안하면 클래스의 접근지정자를 따라감

 

* 싱글톤

- 스프링에서 생성되는 모든 빈은 싱글톤 모드

- JSP도 싱글톤으로 jsp가 서블릿으로 변환되면 계속 그걸로 재사용

- 실무에서 싱글톤 패턴 사용하는 방법은 여러가지가 있는데

- syncronized 키워드 사용은 제일 구현 간단하지만 저 키워드 자체가 lock이 걸려서 진행되기 때문에 성능저하 발생가능

- 요즘엔 Holder 패턴을 많이 쓰는데 classloader 의 특징을 이용해 만든 패턴 >좀 더 자세히 찾아보기

 

* 클래스의 접근지정자

- 클래스에는 public default 만 사용

 

* getter/setter 를 왜 쓰는지

 

* 리플랙션

- 런타임시에 클래스 정보를 가져오는 기법

- 프레임워크를 만든다면 리플랙션은 필수

- 리플랙션하려면 annotation 유지정책을 runtime으로 지정

 

* 클래스의 로딩시점

- 클래스를 참조할때 클래스로더에 올라가고

- static 변수, 메소드 등은 그때 정의됨

 

 

1 – 3)

하나의 클래스로 여러 개의 객체생성 가능

 

2 – 4)

 

3 – 4)

필드, 메소드 생략가능

 

4 – 3)

생성자/메소드 앞뒤에서 모두 선언가능ㅎ지만

생성자와 메소드 내부에서는 선언할수없음

 

 

5 – 1)

생성자를 실행시키지않으면 객체생성 불가능

 

6 – 4)

오버로딩(메소드이름은 같고, 매개변수 형태 다른경우)으로 가능

 

7 – 2)

리턴타입은 같아도 됨

 

8 – 2)

정적블록 내부에서 인스턴스 필드나 인스턴스 메소드를 사용할수없음

사용하고싶으면 내부에서 객체생성후 참조변수로 접근

 

9 – 2)

상수는 초기값 또는 정적블록에서 선언가능

 

10 – 4)

클래스만 복사해서 이동하면 사용할수없음

 

11 – 3)

동일패키지 내에 속한 클래스들은 접근가능

 

12필드, 생성자, 메소드

 

13/14

Public class Member {

 private String name;
 private String id;
 private String password;
 private String age;

 public Member() {}

 public Member(String name, String id) {
   this.name = name;
   this.id = id;
 }
}

 

15

Public class MemberService {
 Public Boolean login(String id, String password) {
	If (“hong”.equals(id) && “12345”.equals(password)) {
	return true;
 }
 Return false;
}

 Public void logout(String id) {
 	System.out.println(id+“님, 로그아웃 되었습니다.”);
 }
}

16

Public class Printer {
  Public void println(int val) {
      System.out.println(val);
  }

  Public void println(boolean val) {
      System.out.println(val);
  }

  Public void println(double val) {
      System.out.println(val);
  }

  Public void println(String val) {
      System.out.println(val);
  }
}

17

Public class Printer {
  Public static void println(int val) {
  	System.out.println(val);
  }
  Public static void println(boolean val) {
  	System.out.println(val);
  }

  Public static void println(double val) {
  	System.out.println(val);
  }

  Public static void println(String val) {
  	System.out.println(val);
  }

}

 

18

Public class ShopService {
  Private static ShopService singleton;
  Private ShopService() {}

  Public static ShopService getInstance() {

    If (singleton==null) { 
    	Return new ShopService();
    }
    else singleton;
  }
}

 

19

Public class Account {

 Public static final MIN_BALANCE=0;
 Public static final MAX_BALANCE=1000000;
 Private int balance;

 Public void setBalance (int balance) {
   if (MIN_BALANCE <= balance && MAX_BALANCE <= balance) {
      This.balance = balance;
   }
   Return this.balance;
  }

  Public int getBalance () {
      Return this.balance;
  }

}

20

 

//  현재 몇번째 array 인지 파악하기 위한 용도 
public static int curArrCnt = 0; 

Private static void createAccount() {
   //scanner 로 입력
  Account acc = new Account(ano, owner, balance);
  System.out.println(“계좌가 생성되었습니다.”);
  accountArray[curArrCnt++] = acc;
}

Private static void accountList() {
  For(int I = 0 ; I < accountArray.lenth; i++) {
    System.out.println(accountArray[i].getAno() + “ ” 
    + accountArray[i].getOwner() + “ “ + accountArray[i].getBalance());
  }
}

Private static void deposit() {
  // scanner 로 계좌번호, 예금액 입력
  Account acc = findAccount(ano);
  Int curBal = Acc.getBalance();
  Acc.setBalance(curBal+balance);
}

Private static void withdraw() {
  // scanner 로 계좌번호, 출금액 입력
  Account acc = findAccount(ano);
  Int curBal = Acc.getBalance();
  Acc.setBalance(curBal-balance);
}

Private static Account findAccount(String ano) {
  For(int I = 0 ; I < accountArray.lenth; i++) {
    If (accountArray[i].getAno() == ano)
    	Return accountArray[i];
  }
}

'Language > Java' 카테고리의 다른 글

자바 커뮤니티3 - 인터페이스  (0) 2019.06.05
자바 커뮤니티2 - 상속  (0) 2019.05.28
Java 문자열 객체  (0) 2018.08.04
Java 배열 선언, 초기화  (0) 2018.08.04
Java 접근지정자 (Access Modifier)  (0) 2018.08.04

자바 문자열 객체

  • String
  • StringBuffer
  • StringBuilder


String 객체

String 객체는 new 연산을 이용해서 객체를 생성하면 인스턴스의 메모리 공간이 변하지 않는다. (immutable)
따라서, + 연산이나 concat을 수행하면 새로운 문자열 객체들이 만들어지고
이를 반복하면 새로운 인스턴스들이 생겨나므로 성능이 낮아진다. 

메모리값이 변하지않으므로 조회 연산에서는 다른 클래스보다 성능이 좋고
그렇기때문에 멀티스레드 환경에서 동기화에 대해 신경쓸 필요가 없다.

> String 객체는 문자열 연산이 적고, 조회가 많은 멀티스레드 환경에 적합


StringBuffer, StringBuilder 객체

String 과 다른 점은 mutable 하다는 점이다.
문자열을 생성하고(new) 변경사항이 생기면 메모리 크기를 늘려서 문자열을 바꾼다.

StringBuffer 와 StringBuilder 는 내부적으로 메소드가 동일하지만
StringBuffer 는 동기화를 지원(syncronized)하고 StringBuilder 는 동기화를 지원하지 않는다는 점에서 다르다.

따라서 멀티스레드 환경에서는 StringBuffer 를 사용하고(thread-safe)
싱글스레드 환경에서는 StringBuilder 를 사용하여 연산속도를 빠르게 하는 것이 적합하다.

> 문자열 연산이 많고 멀티스레드이면 StringBuffer를, 동기화를 신경쓸 필요가 없다면 StringBuildrer 사용


JDK 버전에 따른 String 성능 개선

1.5 버전 이상에서는
String 객체로 연산해도 내부적으로 StringBuilder 로 변환되어 성능상 이슈를 해결했다고 한다.



'Language > Java' 카테고리의 다른 글

자바 커뮤니티2 - 상속  (0) 2019.05.28
자바 커뮤니티1 - Class  (0) 2019.05.22
Java 배열 선언, 초기화  (0) 2018.08.04
Java 접근지정자 (Access Modifier)  (0) 2018.08.04
Java String Constant Pool의 이해  (0) 2018.08.02

배열 선언


int[] num;



배열 생성


num = {1, 2, 3};
num = new int[3];
num = new int[] {1, 2, 3};



메모리 계산


int[] num = new int[10];


int(4byte) * 10 => 40 byte



배열 초기화


int num[] = new int[] {1, 2, 3};
int num[] = {1, 2, 3};


'Language > Java' 카테고리의 다른 글

자바 커뮤니티1 - Class  (0) 2019.05.22
Java 문자열 객체  (0) 2018.08.04
Java 접근지정자 (Access Modifier)  (0) 2018.08.04
Java String Constant Pool의 이해  (0) 2018.08.02
Comparator 인터페이스를 이용한 다중 정렬  (0) 2018.08.01

접근지정자 (Access Modifier) 종류

  • public
  • protected
  • default (아무 키워드도 안붙인 상태)
  • private

public > protected > default > private 순으로 접근 범위


범위

 

 범위

 같은 클래스 내

같은 패키지 내 

 다른 패키지의 

자식클래스

다른 패키지 

 public

 접근 제한 없음

 O

O

O

 protected

 같은 패키지나 클래스

상속받은 클래스

 O

O

O

 

 default

같은 클래스나 패키지 

 O

O

 

 

 private

같은 클래스에서만 

 O

 

 

 



public

접근에 제한이 없다.

protected

같은 패키지 내에서 접근 가능하고
다른 패키지이더라도 상속받은 경우는 클래스 내부에서 접근 가능하다.
but, 다른 패키지 외부에서는 접근 불가능하다.

default

변수나 메소드 선언에 아무 키워드도 붙이지 않은 접근 범위이다.
같은 클래스나 패키지 안에서만 접근 가능하다.

private 

같은 클래스 내부에서만 접근 가능하다.

'Language > Java' 카테고리의 다른 글

자바 커뮤니티1 - Class  (0) 2019.05.22
Java 문자열 객체  (0) 2018.08.04
Java 배열 선언, 초기화  (0) 2018.08.04
Java String Constant Pool의 이해  (0) 2018.08.02
Comparator 인터페이스를 이용한 다중 정렬  (0) 2018.08.01

String Constant Pool의 이해


우연히 생활코딩에서 보게 된 글, 답은 당연히 false 라고 생각했지만 직접 돌려본 결과 true였다.

// true일까요 false 일까요?

String a = "aaa";
String b = "aaa";
if (a == b) {
    System.out.println("true");
} else {
    System.out.println("false");
}

[예제1] 객체 비교 문제



== 연산


Java 에서 == 연산은 객체의 주소값을 비교할 때 사용하고 

문자열의 값을 비교할 때는 equals 함수를 쓴다.


그런데 [예제1] 에서는 ==연산으로 비교했음에도 결과값은 왜 true를 반환할까



String Constant Pool 


답은 String Constant Pool 때문이었다.


먼저 String을 생성하는 방법은 대표적으로 2가지가 있다.

  1. new 연산자 방식
  2. literal을 이용한 방식


String a = new String("aaa"); // new 방식
String b = "aaa"; // literal 방식

[예제2] String 선언 방식



literal 로 String 을 선언한 경우 


String 객체는 내부적으로 intern() 메소드를 호출하게 된다.

intern 메소드는 String Constant Pool 에서 해당 문자열이 존재하는지 검색하고

존재하면 해당 문자열의 주소값을 반환

존재하지 않으면 새로운 주소값을 할당하여 반환한다.


이러한 동작원리에 따라 [예제1] 의 결과값은 true를 반환한다.



intern 메소드


명시적으로 intern 메소드를 호출하면 어떤 결과가 나올지 테스트해보았다.

String a = new String("aaa"); 
String b = "aaa"; 
String c = a.intern();

System.out.println(a == b); // false
System.out.println(b == c); // true


new 연산자로 선언한 a 와 literal 로 선언한 b 객체의 주소값은 다르지만

b와 a의 intern 메소드를 호출한 주소값(c)은 같았다.


따라서 literal 로 생성한 문자열은 스트링풀에 등록되고 내부적으로 고유의 인스턴스를 공유하는 것을 알 수 있다.



String Constant Pool 위치


Java6에서 스트링풀은 Perm 영역에 있었는데 

OutOfMemory(OOM) 문제로 Java7에서는 Heap 영역으로 변경되었다고 한다.


Perm 영역은 고정되어있고 Runtime 시에도 확장되지 않기때문에 Java6 이하 버전에서 intern 메소드를 자주 호출하면 OOM이 발생할 수 있다.



Heap 영역으로 변경 후 이점


Heap 영역으로 변경된 후 스트링 풀에 있는 문자열도 GC 대상이 된다.

따라서 효율적인 메모리 관리가 가능해진다.



스트링 풀 사이즈 설정


  • 스트링풀 사이즈는 -xx:StringTableSize 옵션으로 설정이 가능하다. (디폴트 : 1009)
  • intern 메소드를 자주 사용한다면 사이즈는 디폴트 값보다 높게 설정해야한다.
  • 사이즈 값으로는 소수를 사용해야 한다. (예를 들면 1,000,003)






참고 : https://medium.com/@joongwon/string-%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B3%A0%EC%B0%B0-57af94cbb6bc

'Language > Java' 카테고리의 다른 글

자바 커뮤니티1 - Class  (0) 2019.05.22
Java 문자열 객체  (0) 2018.08.04
Java 배열 선언, 초기화  (0) 2018.08.04
Java 접근지정자 (Access Modifier)  (0) 2018.08.04
Comparator 인터페이스를 이용한 다중 정렬  (0) 2018.08.01

자바에서 객체를 특정 기준으로 정렬하는 경우 Comparable이나 Comparator 인터페이스를 사용



(예제)Comparator 인터페이스를 이용한 다중 정렬

  1. Board 객체를 생성
  2. Comparator 인터페이스를 구현한 MultiComp 클래스 정의
  3. MultiComp 클래스를 이용해 Board 객체 정렬

조건
  • cnt 내림차순
  • cnt 가 같은 경우 date 의 최신순서로 정렬 (내림차순)


Board 객체를 생성

  • date 형식 : 20180801
public class Board {
    int cnt;
    String date;
}

[예제1] Board 객체



Comparator 인터페이스를 구현한 MultiComp 클래스 정의


조건1. cnt 내림차순

조건2. cnt 가 같은 경우 date 의 최신순서로 정렬 (내림차순)

import java.util.Comparator; import com.Board; public class MultiComp implements Comparator< Board > { public MultiComp() { super(); } @Override public int compare(Board o1, Board o2) { int c1 = o1.getCnt(); int c2 = o2.getCnt(); if (c1 < c2) { return 1; } else if (c1 > c2) { return -1; } else { // c1 == c2 // (-1) 내림차순을 위한 부호 변환 return (-1) * (o1.getDate().compareTo(o2.getDate())); } }

[예제2] MultiComp 클래스



MultiComp 클래스를 이용해 Board 객체 정렬

  • Collections.sort 함수를 이용하여 객체 정렬

List< Board> resultList = new ArrayList< Board >();
resultList = db.getXXX(); // DB에서 데이터 가져오기
Collections.sort(resultList, new MultiComp());

'Language > Java' 카테고리의 다른 글

자바 커뮤니티1 - Class  (0) 2019.05.22
Java 문자열 객체  (0) 2018.08.04
Java 배열 선언, 초기화  (0) 2018.08.04
Java 접근지정자 (Access Modifier)  (0) 2018.08.04
Java String Constant Pool의 이해  (0) 2018.08.02

+ Recent posts