자바스크립트(Javascript)

- 객체기반의 스크립트 프로그래밍 언어

- 웹 브라우저 내에서 주로 사용

- 웹 브라우저로만 동작하는 것이 아닌, 서버로도 이용이 가능하다. -> Host API 필요

- 웹에서 사용 가능한 언어를 만들기 위해 프로토타입 기반의 함수형 언어로 만든 언어

- 모카(mocha) -> 라이브스크립트(LiveScript) -> 자바스크립트(Javascript)

-> 표준화 진행 -> 비영리표준기구(ECMA) -> ECMAScript 이름으로 표준화

 

 

JavaScript와 ECMAScript는 같지 않다

- JavaScript = ECMAScript + Client Side Web API(ex.DOM) [FRONT]

                                              + Host API                                   [SERVER]

 

 

ECMAScript

- ECMAScript 2015(버전) = ES6(배포판)

- ES6을 쓰는 이유? : 5에서 6으로 많은 변화가 있었기 때문이다. 그 이후로는 언어가 변한 것 보다는 기능의 추가 정도가 이루어졌다.

 


자바스크립트의 단점 -> fragmentation 현상 

(1) 언어의 모호성

(2) 구현의 어려움

 

 

제이쿼리(jQuery)

- 오픈 소스 기반의 자바스크립트 라이브러리

- 브라우저와 상관없이 동일하게 동작시킬 수 있다는 장점으로, JavasScript가 인기가 많아진 이유중 하나이다.

- 문제점 : 프레임워크가 아닌, 라이브러리라는 한계 -> 라이브러리를 통해 유지 보수하기 어렵다는 문제점

 

 

HTML(HyperText Markup Language) 하이퍼텍스트 마크업 언어

- 프로그래밍 언어 X

- 웹페이지가 어떻게 구조화되어 있는지 브라우저로 알 수 있게 해주는 마크업 언어

- W3C(World Wide Web Consortium)에서 표준 제정

- HTML의 한계인 정형성과 확장성 문제로, 한동안 HTML4.01에서 업데이트를 하지 않았다.

(1) 정형성 : 정답이 없기 때문에 정형성이 없고, 올바르지 않은 코드도 실행이 되기 때문에 유지 보수의 문제점 발생

(2) 확장성 : 정해진 태그로 확장하기 힘들다는 단점

 

 

HTML의 확장성과 정형성 문제 해결

(1) HTML + XML -> XHTML1.0

(2) HTML 보완 -> HTML5 

- HTML5 2014년 표준화

 

 

HTML5

- HTML의 새로운 버전으로 Client Side Technology 기술의 중심이 되는 마크업 언어

- JavaScript의 인기가 많아지기 시작했다.

 

 

스택 프레임(Stack Frame)

- 하나의 메소드에 필요한 메모리 덩어리

- 함수가 호출될때 스택에 매개 변수, 지역 변수, 복귀 주소가 스택에 저장된다.

- 백트래킹에 사용된다.

 

구성 요소

- 매개 변수

- 지역 변수

- 복귀 주소

 

스택 프레임 예제1 - 재귀함수를 이용해서 1~N까지의 수 더하기

public class Solution {
    public void DFS(int n){
        if(n==0) return;
        else {
            DFS(n-1);
            System.out.print(n+" ");
        }
    }

    public static void main(String[] args) {
        Solution T = new Solution();
        T.DFS(3);
    }
}

- DFS(3) 이 main 함수에서 실행

- DFS함수에서 DFS(3)이 5번째 줄에서 DFS(2) -> DFS(1)으로 넘어간다.

- DFS(0)에서 return으로 함수를 탈출하면서

- 스택에 쌓여있던 DFS(3), DFS(2), DFS(1)이 위에부터 pop으로 제거된다.

 

출력

- 1 2 3

 

스택 프레임 예제2 - 재귀함수를 이용해서 10진수 -> 2진수

public class Solution {
    public void DFS(int n){
        if(n==0) return;
        else {
            // System.out.print(n%2); 1101으로 출력됨
            DFS(n/2); // 스택프레임으로 인해서 1011으로 출력됨
        }
    }

    public static void main(String[] args) {
        Solution T = new Solution();
        T.DFS(11);
    }
}

이론 정리

연산자

  • 연산에 사용되는 표시나 기호
  • 피연산자 : 연산되는 데이터
  • 단항, 이항, 삼항 연산자 순서의 우선순위
  • 산술, 비교, 논리, 대입 연산자 순서의 우선순위
  • ++a 속도가 a=a+1 속도보다 빠르다.

String 타입

  • 참조형 타입

비트 연산자

  • 데이터를 bit 단위로 연산
  • 정수 타입만 가능
  • 비트 논리 연산자, 비트 이동 연산자

삼항 연산자

  • 세개의 피연산자를 필요로 하는 연산자
// 조건식 ? 값 또는 연산식(true) : 값 또는 연산식(false)
char grade = (score > 90) ? 'A' : ((score > 80) ? 'B' : 'C');

연습문제

[3-1] 다음 연산의 결과를 적으시오.

class Exercise3_1 {
    public static void main(String[] args){
        int x = 2;
        int y = 5;
        char c = 'A'; // 'A'의 문자 코드는 65
        
        System.out.println(1 + x << 33);
        System.out.println(y >= 5 || x < 0 && x > 2);
        System.out.println(y += 10 - x++);
        System.out.println(x+=2);
        System.out.println(!('A' <= c && c <= 'Z'));
        System.out.println('C'-c);
        System.out.println('5'-'0');
        System.out.println(c+1);
        System.out.println(++c);
        System.out.println(c++);
        System.out.println(c);
    }
}
  • 풀이
  • 1. 1+2 (3를 33만큼 왼쪽으로 이동 -> (32+1bit)1번만 이동 0011 -> 0110 = 6 2. true || false && false = false 논리연산자 &&가 ||보다 우선순위가 더 높다 true || true = true 3. 15-2++ = 13 4. (2++) + 2 = 5 5. !(true && true) = false 6. 67-65 = 2 7. 5 8. 66 9. B 10. B 11. C

[3-2] 아래의 코드는 사과를 담는데 필요한 바구니(버켓)의 수를 구하는 코드이다. 만일 사과의 수가 123개이고 하나의 바구니에는 10개의 사과를 담을 수 있다면, 13개의 바구니가 필요할 것이다. (1)에 알맞은 코드를 넣으시오.

class Exercise3_2 {
    public static void main(String[] args){
        int numOfApples = 123; // 사과의 개수
        int sizeOfBucket = 10; 
// 바구니의 크기(바구니에 담을 수 있는 사과의 개수)
        int numOfBucket = ( /*(1)*/ ); 
// 모든 사과를 담는데 필요한 바구니의 수
        
        System.out.println("필요한 바구니의 수 :"+numOfBucket);
    }
}
[실행결과]
13
  • 풀이
  • // numOfApples/sizeOfBucket+1; 반례 : 나머지가 0 인경우 ((numOfApples/sizeOfBucket)==0) ? numOfApples/sizeOfBucket : numOfApples/sizeOfBucket+1

[3-3] 아래는 변수 num의 값에 따라 ‘양수’, ‘음수’, ‘0’을 출력하는 코드이다. 삼항 연산자를 이용해서 (1)에 알맞은 코드를 넣으시오. (삼항 연산자 2번 사용)

class Exercise3_3 {
    public static void main(String[] args){
        int num = 10;
        System.out.println( /* (1) */ );
    }
}
[실행결과]
양수
  • 풀이
  • (num>0) ? "양수" : ((num<0) ? "음수" : '0')

[3-4] 아래는 변수 num의 값 중에서 백의 자리 이하를 버리는 코드이다. 만일 변수 num의 값이 ‘456’이라면 ‘400’이 되고, ‘111’이라면 ‘100’이 된다. (1)에 알맞은 코드를 넣으시오.

class Exercise3_4 {
    public static void main(String[] args){
        int num = 456;
        System.out.println( /* (1) */ );
    }
}
[실행결과]
400
  • 풀이
  • (num/100)*100

[3-5] 아래는 변수 num의 값 중에서 일의 자리 1로 바꾸는 코드이다. 만일 변수 num의 값이 ‘333’이라면 ‘331’이 되고, ‘777’이라면 ‘771’이 된다. (1)에 알맞은 코드를 넣으시오.

class Exercise3_5 {
    public static void main(String[] args){
        int num = 333;
        System.out.println( /* (1) */ );
    }
}
[실행결과]
331
  • 풀이
  • ((num/10)*10)+1

[3-6] 아래는 변수 num의 값보다 크면서도 가장 가까운 10의 배수에서 변수 num의 값을 뺀 나머지를 구하는 코드이다. 예를 들어, 24의 크면서도 가장 가까운 10의 배수는 30이다. 19의 경우 20이고, 81의 경우 90이 된다. 30에서 24를 뺀 나머지는 6이기 때문에 변수 num의 값이 24라면 6을 결과로 얻어야 한다. (1)에 알맞은 코드를 넣으시오.

class Exercise3_6 {
    public static void main(String[] args){
        int num = 24;
        System.out.println( /* (1) */ );
    }
}
[실행결과]
6
  • 풀이
  • (((num/10)+1)*10) - num

[3-7] 아래는 화씨(Fahrenheit)를 섭씨(Celsius)로 변환하는 코드이다. 변환공식이 ‘C’ = 5/9 x (F - 32)’ 라고 할 때, (1)에 알맞은 코드를 넣으시오. 단, 변환 결과값은 소수점 셋째자리에서 반올림해야한다. (Math.round()를 사용하지 않고 처리할 것)

class Exercise3_7 {
    public static void main(String[] args){
        int fahrenheit = 100;
        float celcius = ( /* (1) */ );

        System.out.println("Fahrenheit:"+fahrenheit);
        System.out.println("Celcius:"+celcius);
    }
}
[실행결과]
Fahrenheit:100
Celcius:37.78
  • 풀이
  • (int)((5/9f * (fahrenheit - 32))*100 + 0.5) / 100f; // 1. 37.77778 * 100 // 2. (1)+0.5 // 3. (int)(2) // 4. (3)/100f

[3-8] 아래 코드의 문제점을 수정해서 실행결과와 같은 결과를 얻도록 하시오.

class Exercise3_8 {
    public static void main(String[] args){
        byte a = 10;
        byte b = 20;
        byte c = a + b;

        char ch = 'A';
        ch = ch + 2;

        float f = 3/2;
        long l = 3000 * 3000 * 3000;

        float f2 = 0.1f;
        double d = 0.1;

        boolean result = d==f2;

        System.out.println("c="+c);
        System.out.println("ch="+ch);
        System.out.println("f="+f);
        System.out.println("l="+l);
        System.out.println("result="+result);
    }
}
[실행결과]
c=30
ch=C
f=1.5
l=27000000000
result=true
  • 풀이
  • byte c = (byte)(a + b); ch = (char)(ch + 2); float f = 3/2f; long l = 3000 * 3000 * 3000L; boolean result = (float)d==f2;

[3-9] 다음은 문자형 변수 ch가 영문자(대문자 또는 소문자)이거나 숫자일 때만 변수 b의 값이 true가 되도록 하는 코드이다. (1)에 알맞은 코드를 넣으시오.

class Exercise3_9 {
    public static void main(String[] args){
        char ch = 'z';
        boolean b = ( /* (1) */ );
        System.out.println(b);
    }
}
[실행결과]
true
  • 풀이
  • (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')

[3-10] 다음은 대문자를 소문자로 변경하는 코드인데, 문자 ch에 저장된 문자가 대문자인 경우에만 소문자로 변경한다. 문자코드는 소문자가 대문자보다 32만큼 더 크다. 예를들어 ‘A’의 코드는 65이고, ‘a’의 코드는 97이다. (1)~(2)에 알맞은 코드를 넣으시오.

class Exercise3_10 {
    public static void main(String[] args){
        char ch = 'A';
        char lowerCase = ( /* (1) */ ) ? ( /* (2) */ ) : ch;

        System.out.println("ch:"+ch);
        System.out.println("ch to lowerCase:"+lowerCase);
    }
}
[실행결과]
ch:A
ch to lowerCase:a
  • 풀이
  • (ch >= 65 && ch < 97) ? (char)(ch+32)

이론 정리

변수(variable)

  • 값을 저장할 수 있는 메모리의 공간
  • 첫 번째 글자는 문자 or ‘&’, ‘_’ → 숫자, 예약어 불가능

리터럴(literal)

  • 소스 코드 내에서 직접 입력된 값
  • 정수, 실수, 문자, 논리 리터럴

데이터 타입

  • 기본 타입(primitive) : 정수, 실수, 문자, 논리 리터럴을 직접 저장하는 타입
    • 정수 타입(byte, char, short, int, long)
    • 실수 타입(float, double)
    • 논리 타입(boolean)

타입 변환

  • 자동(묵시적) 타입 변환
    • byte → char(음수X) : 불가능
  • 강제(명시적) 타입 변환 = 캐스팅(casting)
    • int → char : 불가능
    • 실수 → 정수 : 소수점이 버려진다.

연습문제

[2-1] 다음 표의 빈 칸에 8개의 기본형(primitive type)을 알맞은 자리에 넣으시오.

  • 풀이1byte2byte4byte8byte
    논리형 boolean      
    문자형   char    
    정수형 byte short int long
    실수형     float double

[2-2] 주민등록번호를 숫자로 저장하고자 한다. 이 값을 저장하기 위해서는 어떤 자료형(data type)을 선택해야 할까? regNo라는 이름의 변수를 선언하고 자신의 주민등록번호로 초기화 하는 한 줄의 코드를 적으시오.

  • 풀이
    long regNo = 1234561234567L; 
    // long타입 컴파일러에게 4byte가 아닌 8byte를 알려주기 위해 L를 뒤에 붙여준다.
    
  • 예시) 123456-1234567 = 13자리

[2-3] 다음의 문장에서 리터럴, 변수, 상수, 키워드를 적으시오.

int i = 100;
long l = 100L;
final float PI = 3.14f;
  • 리터럴 :
  • 변수 :
  • 키워드 :
  • 상수 :
  • 풀이
    • 리터럴 : 100, 100L, 3.14f
    • 변수 : i, l
    • 키워드 : int, long, final, float
    • 상수 : PI

[2-4] 다음 중 기본형(primitive type)이 아닌 것은?

  1. int
  2. Byte
  3. double
  4. boolean
  • 풀이
    • 기본형X : b(Byte) → byte
    • 기본형 : a(int), c(double), d(boolean)

[2-5] 다음 문장들의 출력결과를 적으세요. 오류가 있는 문장의 경우, 괄호 안에 ‘오류’ 라고 적으시오.

System.out.println("1" + "2") -> ( 12 )
System.out.println(true + "") -> ( true )
System.out.println('A' + 'B') -> ( 131 )
System.out.println('1' + 2) -> ( 51 )
System.out.println('1' + '2') -> ( 99 )
System.out.println('J' + "ava") -> ( Java )
System.out.println(true + null) -> ( 오류 )
  • 풀이
  • “1” + “2” = 12
  • ‘A’ + ‘B’ = 65 + 66 = 131
  • ‘1’ + ‘2’ = 49 + 50 = 99
  • true + null = 오류
    • 문자와 숫자가 같이 쓰일 때, 자동으로 아스키코드로 변환되서 사용된다.
  • ‘J’ + “ava” = Java
  • ‘1’ + 2 = 49 + 2 = 51
  • true + “” = true
  •  

[2-6] 다음 중 키워드가 아닌 것은?(모두 고르시오)

  1. if
  2. True
  3. NULL
  4. Class
  5. System
  • 풀이
    • True → true
    • NULL → null
    • Class → class

[2-7] 다음 중 변수의 이름으로 사용할 수 있는 것은? (모두 고르시오)

  1. $ystem
  2. channel#5
  3. 7eleven
  4. If
  5. 자바
  6. new
  7. $MAX_NUM
  8. hello@com
  • 풀이
    1. $ystem → 특수문자 $ 사용 가능
    2. channel#5 → 특수문자 # 불가능
    3. 7eleven → 앞에 숫자 불가능
    4. If → 가능
    5. 자바 → 한글 불가능
      • 이클립스에서는 한글 사용 가능!!!
    6. new → 예약어 불가능
    7. $MAX_NUM → 특수문자 $ 사용 가능
    8. hello@com → 특수문자 @ 불가능

[2-8] 참조형 변수(reference type)와 같은 크기의 기본형(primitive type)은? (모두 고르시오)

  1. int
  2. long
  3. short
  4. float
  5. double
  • 풀이
    • 참조형 변수는 64bit JVM을 사용하면 8byte : double
    • 32bit JVM을 사용하면 4byte : int, float

[2-9] 다음 중 형 변환을 생략할 수 있는 것은? (모두 고르시오)

byte b = 10;
char ch = 'A;
int i = 100;
long l = 1000L;

a. b = (byte)i;
b. ch = (char)b;
c. shrot s = (short)ch;
d. float f = (flaot)l;
e. i = (int)ch;
  • 풀이
    1. int(4) → byte(1) 크기가 작기 때문에 불가능
    2. byte(1) → char(2) 음수는 변환 불가능
    3. char(2) → short(2) 크기는 같지만, 음수 변환 불가능
    4. long(8) → float(4) 크기가 작아서 실수 생략 가능하므로 가능
    5. char(2) - int(4) 가능

[2-10] char 타입의 변수에 저장될 수 있는 정수 값의 범위는? (10진수로 적으시오)

  • 풀이
    • 0~65536 = 2^16-1

[2-11] 다음 중 변수를 잘못 초기화 한 것은? (모두 고르시오)

a. byte b = 256;
b. char c = '';
c. char answer = 'no';
d. float f = 3.14
e. double d = 1.4e3f;
  • 풀이
    1. byte : -128~127 불가능
    2. char : 한개의 문자가 아니라 불가능
    3. char : 두개의 문자 불가능
    4. float : 리터럴 뒤에 f가 오지 않아서 불가능

[2-12] 다음 중 main 메서드의 선언부로 알맞은 것은? (모두 고르시오)

a. public static void main(String[] args)
b. public static void main(String args[])
c. public static void main(String[] arv)
d. public void static main(String[] args)
e. static public void main(String[] args)
  • 풀이
    • a, b, c, e

[2-13] 다음 중 타입과 기본값이 잘못 연결된 것은? (모두 고르시오)

a. boolean - false
b. char - '\\u0000' // 16진수 저장
c. float - 0.0
d. int - 0
e. long - 0
f. String - ""
  • 풀이e. 리터럴 뒤에 L 생략되어 있어서 불가능
  • f. String의 기본 값은 null
  • c. 리터럴 뒤에 f 생략되어 있어서 불가능

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 스택 프레임(Stack Frame)  (0) 2022.06.28
[자바의 정석] 연습문제 2. 연산자  (0) 2022.06.23
[JAVA] 자바 메모리 구조 - Heap, Stack, JVM, GC  (0) 2022.06.23
Ch06. 클래스  (0) 2022.01.02
Ch05. 참조 타입  (0) 2022.01.01

자바 실행 과정

- 프로그램 실행

- 자바 컴파일러 javac 에서 소스코드 .java 를 읽어서 바이트 코드 .class 로 변환한다.

- class loader로 class파일을 JVM으로 로딩

- class 파일들을 Execution engine으로 해석

- 해석된 바이트 코드를 Runtime Data areas에 배치되어 수행

 

JVM 

- java application을 class loader를 통해 읽어서 자바 API와 함께 실행한다.

- JAVA와 OS사이의 중개자 역할

- 자바 byte code를 실행할 수 있는 주체

- JAVA가 다른 언어에 비해 OS에 영향을 받지 않고 사용 가능하도록 해주는 장점이 있다.

- 다른 언어는 malloc 같은 메모리 할당을 하고 해제를 해줘야 하지만 자바는 GC를 이용해서 메모리 관리를 대신 해준다.

- 스택 기반의 가상머신(정적)

 

GC

- 동적으로 할당된 메모리 영역에서 사용하지 않는 영역을 GC가 할당 해제한다.

 

Stack

- 정적 메모리 할당 영역

- Primitive 타입 

- 메모리가 thread당 하나씩 할당

- 다른 thread끼리 stack 영역 접근 불가능 

 

Heap

- 동적 메모리 할당 영역

- Object 타입

- heap 영역의 Object를 가리키는 참조 변수가 Stack에 할당

- stack과 다르게 thread가 여러개 있어도, heap은 1개의 영역만 존재

 

STACK HEAP
빠른 접근 속도 느린 접근 속도
정적 메모리 할당 동적 메모리 할당
메모리 크기 제한 (OS에 영향) 메모리 크기 제한 X
Primitive type Object type
문제점 memory shortage 문제점 memory fragmentation
  ralloc(), new
선형적 계층적 구조

 

'프로그래밍 > JAVA' 카테고리의 다른 글

[자바의 정석] 연습문제 2. 연산자  (0) 2022.06.23
[자바의 정석] 연습문제 1.변수와 타입  (0) 2022.06.23
Ch06. 클래스  (0) 2022.01.02
Ch05. 참조 타입  (0) 2022.01.01
Ch04. 조건문과 반복문  (0) 2022.01.01
객체 지향 프로그래밍
  • 객체들을 먼저 만들고, 이것들을 하나씩 조립해서 완성된 프로그램을 만드는 기법
  • 객체(Object) : 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고, 다른 것과 식별 가능한 것.
    • 속성 = 필드(field)
    • 동작 = 메소드(method) : 객체들 사이의 상호작용 수단은 메소드
  • 객체 모델링(Object Modeling) : 현실 세계의 객체를 소프트웨어 객체로 설계하는 것
  • 메소드 호출 : 객체가 다른 객체의 기능을 이용하는 것
  • 객체 간의 관계 : 집합 관계, 사용 관계, 상속 관계

[객체 간의 관계]

 

객체 지향 프로그래밍의 특징
  • 캡슐화(Encapsulation)
    • 객체의 필드, 메소드를 하나로 묶고, 실제 구현 내용을 감추는 것
    • 외부 객체는 객체의 내부 구조를 알 수 없다.
    • 자바 언어는 캡슐화된 멤버를 노출시킬 것인지, 숨길 것인지 접근 제한자(Access Modifier) 사용
  • 상속(Inheritance) 
    • 부모가 가지고 있는 재산을 자식에게 물려주는 것
    • 코드의 중복 최소화 가능
    • 유지 보수 시간 최소화
  • 다형성(Polymorphism) 
    • 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질
    • 자바는 다형성을 위해 부모 클래스 또는 인터페이스의 타입 변환을 허용
    • 부모 타입에는 모든 자식 객체 대입 가능
    • 인터페이스 타입에는 모든 구현 객체가 대입 가능
    • 다형성으로 인해 객체는 부품화가 가능

 

객체와 클래스
  • 현실에서 객체는 설계도를 바탕으로 만들어진다.
  • 자바에서의 설계도는 클래스(class)이다.
  • 클래스(class) 
    • 객체를 생성하기 위한 필드와 메소드가 정의되어 있다.
    • 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스(instance)라고 한다.
    • 인스턴스화 : 클래스로부터 객체를 만드는 과정
  • 객체지향 프로그래밍 개발 3단계
    1. 클래스 설계
    2. 설계된 클래스를 가지고 사용할 객체 생성
    3. 생성된 객체 사용

 

클래스 선언
  • 클래스 이름은 자바의 식별자 작성 규칙을 따른다.
  • 일반적으로 소스 파일당 동일한 이름의 하나의 클래스를 선언한다.
  • 두 개 이상도 가능하지만, 컴파일을 하면 바이트 코드 파일은 클래스를 선언한 개수만큼 생기기 때문에, 파일 이름과 일치하지 않는 클래스 선언에 public 접근 제한자를 붙이면 컴파일 에러가 발생한다.

[자바의 식별자 작성 규칙]

 

객체 생성과 클래스 변수
  • new 연산자 
    • 클래스로부터 객체를 생성하는 방법.
    • 연산자 뒤에 생성자가 온다.
    • new 연산자로 생성된 객체는 메모리 힙(heap) 영역에 생성된다.
    • 힙 영역에 객체를 생성시킨 후, 객체의 주소를 리턴한다.
클래스 변수 = new 클래스();

[new 연산자 사용 후 메모리 구조]

 

  • 클래스의 2가지 용도
    • 라이브러리(API)용 : 다른 클래스에서 이용할 목적으로 설계
    • 실행용 : main() 메소드를 제공하는 역할
  • 프로그램을 하나의 클래스로 구성할 수 있지만, 객체 지향 프로그램은 대부분 라이브러리와 실행 클래스가 분리되어 있다.
public class studnet {  // 라이브러리 클래스
}
public class StudentExample {   // 실행 클래스
    public static void main(String[] args){
        ...
    }
}

 

클래스의 구성 멤버
  • 필드(Field)
    • 객체의 데이터가 저장되는 곳
    • 변수와 비슷하지만. 변수는 생성자와 메소드 내에서만 사용되고 생성자는 메소드가 실행 종료되면 자동 소멸한다. 하지만 필드는 메소드 전체에서 사용되고, 객체가 소멸되지 않으면 객체와 함께 존재한다.
  • 생성자(Constructor)
    • 객체 생성 시 초기화 역할 담당
    • 생성자는 메소드와 비슷하지만, 클래스 이름으로 되어 있고, 리턴 타입이 없다.
    • 생성자가 성공적으로 실행되면 힙(heap) 영역에 객체가 생성되고 객체의 주소가 리턴된다.
    • 모든 클래스는 생성자가 반드시 존재한다. 
      • 기본 생성자 
        • 중괄호 블록 내용이 비어있는 기본 생성자. 클래스 내부에 생성자 선언을 생략하면 컴파일러가 자동으로 추가한다.
        • 클래스에 생성자를 선언하지 않아도 new 연산자 뒤에 기본 생성자를 호출해서 객체 생성이 가능하다.

[기본 생성자 자동 생성]
[기본 생성자로 객체 생성 가능]

  • 메소드(Method)
    • 객체의 동작에 해당하는 실행 블록
    • 객체 간의 데이터 전달 수단
public class ClassName{
    int fieldName; // 필드
    ClassName() {...} // 생성자
    void methodName() {...} // 메소드
}

외부 클래스에서 Car 필드 값 읽기와 변경
public class Car {
    // 필드
    String company = "현대자동차";
    String model = "그랜저";
    String color = "검정";
    int maxSpeed = 350;
    int speed;
}
public class CarExample {
    public static void main(String[] args){
        // 객체 생성
        // 다른 클래스의 필드 값을 사용하기 위해서는 다른 클래스의 객체를 생성해야한다.
        Car myCar = new Car();

        // 필드 값 읽기
        System.out.println("제작회사 " + myCar.company);
        System.out.println("모델명 " + myCar.model);
        System.out.println("색깔 " + myCar.color);
        System.out.println("최고속도 " + myCar.maxSpeed);
        System.out.println("현재속도 " + myCar.speed);

        // 필드 값 변경
        myCar.speed = 60;
        System.out.println("수정된 속도 " + myCar.speed);
    }
}

 

기본 생성자 대신 명시적 생성자 선언
  • 명시적 생성자의 매개 변수는 new 연산자로 생성자를 호출할 때 외부의 값을 생성자 블록 내부로 전달한다.
public class Car {
    // 생성자
    Car(String color, int cc) {
    }
}
public class CarExample {
    public static void main(String[] args){
        Car myCar = new Car("검정", 3000);
        // Car myCar  new Car();
        // 생성자가 명시적으로 선언되어 있을 경우 기본 생성자 호출이 불가능
    }
}

 

필드 초기화
  • 클래스로부터 객체가 생성될 때, 필드는 기본 초기 값으로 자동 설정
  • 다른 값으로 초기화하는 2가지 방법
    1. 필드를 선언할 때 초기값을 준다.
    2. 생성자에서 초기값을 준다. (객체 생성 시점에 외부에서 제공되는 다양한 값들로 초기화될 경우)
public class Korean {
    // 필드
    String nation = "대한민국"; // 필드에서 초기화
    String name;
    String ssn;


    // 생성자
    // 생성자에서 초기화
    public Korean(String n, String s) {
        name = n;
        ssn = s;
    }
}
  • 생성자의 매개 변수 이름은 필드와 동일한 이름을 갖는 매개 변수를 사용한다. 그렇게 되면 필드와 매개 변수 이름이 동일하기 때문에 생성자 내부에서 해당 필드에 접근이 불가능하다. (매개 변수가 사용 우선순위가 높기 때문)
  • 해결 방법 : 필드 앞에 this를 붙인다.
    public Korean(String name, String ssn) {
        this.name = name; // this.필드 = 매개변수
        this.ssn = ssn;
    }
}

 

생성자 오버로딩(Overloading)
  • 매개 변수를 달리하는 생성자를 여러 개 선언하는 것
  • 다양한 방법으로 객체를 생성할 수 있도록 사용한다.
  • 매개 변수의 타입, 개수, 순서를 다르게 선언한다.
public class Car {
    Car(){}
    Car(String model) {}
    Car(String model, String color) {}
}
  • 매개 변수의 이름만 바꾸는 것은 생성자 오버로딩이 아니다.
Car(String color, String model) {}
Car(String model, String color) {}
public class Car {
    // 필드
    String company = "현대자동차";
    String model;
    String color;
    int maxSpeed;

    // 생성자
    Car(){
    }
    Car(String model) {
        this(model, "은색", 250); // 맨 아래 생성자 호출
    }
    Car(String model, String color) {
        this(model, color, 250); // 맨 아래 생성자 호출
    }
    Car(String model, String color, int maxSpeed){
        this.model = model;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }
}

 

메소드
  • 메소드 : 객체의 동작에 해당하는 중괄호 블록
  • 리턴타입, 메소드이름, 매개변수선언
  • 시그너처(signature) : 메소드 선언부
  • 메소드 이름은 자바 식별자 규칙에 맞게 사용한다.
    • 소문자로 작성, 단어의 첫머리는 대문자
public class Caculator {
    // 메소드
    void powerOn(){
        System.out.println("전원을 켭니다.");
    }
    int plus(int x, int y){
        int result = x + y;
        return result;
    }
}

public class CaculratorExample {
    public static void main(String[] args){
        Caculator myCalc = new Caculator();
        myCalc.powerOn(); // 메소드 호출
        
        int result1 = myCalc.plus(5, 6);
        System.out.println(result1);
    }
}
  • 매개 변수의 수를 모를 경우 : 매개 변수를 배열 타입으로 선언한다.
public class Computer {
    // 첫번째 방법 생성자
    int sum1(int[] values){
        int sum = 0;
        for(int i=0; i<values.length; i++){
            sum += values[i];
        }
        return sum;
    }
    
    // 두번째 방법 생성자
    int sum2(int ... values) {
        int sum = 0;
        for (int i = 0; i < values.length; i++) {
            sum += values[i];
        }
        return sum;
    }
}

public class ComputerExample {
    public static void main(String[] args){
        Computer myCom = new Computer(); // 객체 생성
        
        int[] values1 = {1, 2, 3};
        int result1 = myCom.sum1(values1);
        System.out.println(result1);
        
        int result2 = myCom.sum1(new int[] {1,2,3,4,5});
        System.out.println(result2);
        
        int result3 = myCom.sum2(1, 2, 3);
        System.out.println(result3);
    }
}

 

메소드 오버로딩(overloading)
  • 클래스 내부에 같은 이름의 메소드를 여러 개 선언하는 것
  • 매개 값을 다양하게 받아 처리할 수 있도록 사용한다.
  • 매개 변수의 타입, 개수, 순서 중 하나가 달라야 한다.

 

인스턴스 멤버와 this
  • 인스턴스 멤버
    • 객체(인스턴스)를 생성한 후 사용할 수 있는 필드와 메소드
    • 객체 없이는 사용 불가능
    • 인스턴스 필드, 인스턴스 메소드
  • this 
    • 객체 내부에서도 인스턴스 멤버에 접근하기 위해 this를 사용한다.
Car(String model) {
    this(model, "은색", 250); 
}
void setModel(String model){
    this.model = model;
}

 

정적 멤버와 static
  • 정적 멤버(클래스 멤버)
    • 클래스에 고정된 멤버
    • 객체를 생성하지 않고 사용할 수 있는 필드와 메소드
    • 정적 필드, 정적 메소드
  • 클래스 로더가 클래스(바이트 코드)를 로딩해서 메소드 메모리 영역에 적재할 때 클래스별로 관리된다.
  • 클래스 이름으로 접근할 수 있다. 객체 참조 변수로도 가능하지만, 사용 시 경고 표시가 나타난다.
  • 정적 필드는 필드 선언과 동시에 초기 값을 주는 것이 보통이지만, 계산이 필요한 경우 정적 블록을 사용한다.
public class Television {
    static String company = "Samsung"; // 보통 필드에서 초기값 결정 
    static String model = "LCD";
    static String info;
    
    static { // 정적 블록 사용
        info = company + "_" + model;
    }
}
  • 정적 블록과 메소드에서 인스턴스 필드와 메소드를 사용할 수 없다.
  • 해결 방법은 객체를 먼저 생성(new 연산자 사용)하고 참조 변수로 접근해야 한다.
public class ClassName {
    // 인스턴스 필드와 메소드
    int field1;
    void method1() {}
    
    // 정적 필드와 메소드
    static int field2;
    static void method2() {}
    
    // 정적 블록
    static {
        field1 = 10; // 컴파일 에러
        method1();  // 컴파일 에러
        field2 = 10;
        method2();
    }
    
    // 정적 메소드
    static void Method3 {
        this.field1 = 10; // 컴파일 에러
        this.method1();  // 컴파일 에러
        field2 = 10;
        method2();
    }
}

 

싱글톤(Singleton)
  • 단 하나의 객체만 만드는 객체를 싱글톤이라고 한다.
  • 클래스 외부에서 new 연산자로 생성자를 호출할 수 없도록 해야 한다.
  • 호출할 수 없도록 생성자 앞에 private 접근 제한자를 붙여준다.
  • 클래스 내부에서 new 연산자로 생성자 호출이 가능하기 때문에, 정적 필드도 private 접근 제한자를 붙인다. 
  • 외부에서 호출할 수 있도록, 정적 메소드인 getInstance()를 선언하고, 정적 필드에서 참조하고 있는 자신의 객체를 리턴해준다.
public class Singleton {
    // private + 정적 필드
    private static Singleton singleton = new Singleton();
    
    // private + 생성자
    private Singleton(){}
    
    // private + 정적 메소드
    static Singleton getInstance(){
        return singleton;
    }
}

// 외부에서 객체를 얻는 유일한 방법
public class SingleExample(){
    public static void main(String[] args){
        Singleton obj = Singleton.getInstance();
    }
}

 

final 필드와 상수
  • final 필드
    • 초기 값이 저장되면 이것이 최종적인 값이 되어서 프로그램 실행 도중에 수정할 수 없다.
  • final 필드 초기값 주는 2가지 방법
    1. 필드 선언 시에 준다.
    2. 생성자에서 준다.
public class Person {
    final String nation = "Korea"; // 수정 불가
    final String ssn;
    String name;
    
    public Person(String ssn, String name){
        this.ssn = ssn;
        this.name = name;
    }
}
  • 상수(static final)
    • 변하지 않는 값
    • final 필드는 객체마다 저장되고, 생성자의 매개값을 통해서 여러 가지 값을 가질 수 있기 때문에 상수가 될 수 없다.
    • 상수는 static + final 
    • 상수 이름은 모두 대문자
public class Earth {
    static final double EARTH_RADIUS = 6400;
    static final double EARTH_SURFACE_AREA;
    
    static {
        EARTH_SURFACE_AREA = 4 * Math.PI * EARTH_RADIUS * EARTH_RADIUS;
    }
}

 

패키지(Package)
  • 클래스를 체계적으로 관리하기 위해서 사용
  • 패키지의 물리적 형태는 파일 시스템의 폴더
  • 클래스를 식별해준다.
  • 상위패키지.하위패키지.클래스
  • package 상위패키지.하위패키지;
  • 모두 소문자로 작성
  • 중복되지 않도록 보통 회사의 도메인 이름으로 패키지 작성 
  • 패키지 폴더를 자동으로 생성하려면 javac 명령어 다음 -d 옵션을 추가해 패키지가 생성될 경로를 지정해줘야한다.
    • javac -d 경로

 

import문
  • 다른 패키지에 속하는 클래스를 사용할 수 있는 방법
  • * 은 패키지에 속하는 모든 클래스 
  • import 문으로 지정된 패키지의 하위 패키지는 import 대상이 아니다.

 

접근 제한자(Access Modifier)
  • 객체 생성을 막기 위해 생성자를 호출하지 못하게 하거나 객체의 특정 데이터를 보호하기 위해서 해당 필드에 접근하지 못하도록 막아준다.
  • public, protected, default, private
  • 클래스에 적용할 수 있는 접근 제한 : public, default

[접근 제한자 종류]

 

Getter와 Setter 메소드
  • 객체 지향 프로그래밍에서는 객체의 무결성을 유지하기 위해, 외부의 직접적 접근을 막는다.
  • 메소드를 통해 데이터를 변경하는 방법을 선호한다.
  • Setter : 검증을 통해 유효한 값만 데이터로 저장 가능 (ex. 음수 검증)
  • Getter : 객체 외부에서 객체 필드값을 사용하기 부적절한 경우, 메소드에서 필드 값 가공 후 외부로 전달
private 타입 fieldName;

// Getter
public 리턴타입 getFieldName(){
    return fieldName;
}

// Setter
public void setFieldName(타입 fieldName){
    this.fieldName = fieldName;
}

 

어노테이션(Annotation)
  • 메타데이터(metadata)라고 볼 수 있다.
    • 애플리케이션에서 처리해야 하는 데이터가 아니라, 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지 알려주는 정보
  • 어노테이션의 3가지 용도
    • 컴파일러에게 코드 문법 에러를 체크하도록 정보 제공
      • 대표적인 예시 : @Override (메소드가 오버라이드된 것인지 컴파일러에게 알려주고, 제대로 되지 않았으면 에러 발생)
    • 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보 제공
    • 실행 시 특정 기능을 실행하도록 정보 제공
  • 어노테이션 타입 정의 방법
    • public @interface AnnotationName {}
    • 엘리먼트(element)를 멤버로 가질 수 있다.
      • 타입 element() [default 값];
      • 엘리먼트 타입 : int, double, String, 열거, Class 타입 등등
  • 어노테이션 타입 적용 방법
    • @AnnotationName
  • 어노테이션 적용 대상 : java.lang.annotation.ElementType 열거 상수로 정의
    • TYPE, ANNOTATION_TYPE, FIELD, CONSTRUCTOR, METHOD, LOCAL_VARIABLE, PACKAGE
    • @Target 사용
  • 어노테이션 유지 정책 : java.lang.annotation.RetentionPolicy 열거 상수로 정의
    • SOURCE, CLASS, RUNTIME
    • @Retention 사용
  • 리플렉션(Reflection) : 런타임 시에 클래스의 메타 정보를 얻는 기능
    • java.lang.refelct

'프로그래밍 > JAVA' 카테고리의 다른 글

[자바의 정석] 연습문제 1.변수와 타입  (0) 2022.06.23
[JAVA] 자바 메모리 구조 - Heap, Stack, JVM, GC  (0) 2022.06.23
Ch05. 참조 타입  (0) 2022.01.01
Ch04. 조건문과 반복문  (0) 2022.01.01
Ch03. 연산자  (0) 2022.01.01
데이터 타입 분류
  • 자바의 데이터 타입
    • 기본 타입(primitive type) : 정수, 실수, 문자, 논리 리터럴을 저장하는 타입. 
    • 참조 타입(reference type) : 객체(object)의 번지를 참조하는 타입. 
      • 배열, 열거, 클래스, 인터페이스 타입

[데이터 타입의 종류]
[기본 타입과 참조 타입 변수]

// 기본 타입 변수
int age = 25;
double price = 100.5;

// 참조 타입 변수
String name = "신용권";
String hobby = "독서";
  • 변수는 스택 영역에 생성되고 객체는 힙 영역에 생성된다.
  • String 클래스 변수는 name과 hobby에 대한 힙 영역 주소 값(100, 200)을 가지고 있다. 

[변수의 스택 영역과 객체의 힙 영역]

 

메모리 사용 영역

[메모리 사용 세부 영역]

  • 메소드(Method) 영역
    • 코드에서 사용되는 클래스들을 클래스 로더로 런타임 상수풀, 필드 데이터, 메소드 데이터, 메소드 코드, 생성자 코드 등을 분류해서 저장한다. 
    • JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역
  • 힙 영역(Heap) 영역
    • 객체와 배열이 생성되는 영역
    • JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다.
    • 참조하는 변수나 필드가 없으면 JVM은 Garbage Collector를 실행시켜 쓰레기 객체를 힙 영역에서 자동으로 제거한다.
  • JVM 스택(stack) 영역
    • 각 스레드마다 하나씩 존재하고, 스레드가 시작될 때 할당된다.
    • JVM 스택은 메소드를 호출할 때마다 프레임(Frame) 추가(push)하고, 메소드가 종료되면 해당 프레임 제거(pop)
    • 프레임 내부의 로컬 변수 스택은 기본 타입 변수와 참조 타입 변수가 추가(push) 되거나 제거(pop)된다. 변수가 생성되는 시점은 초기화가 될 때, 제거되는 시점은 블록을 벗어나는 경우이다. 

 

 참조 변수의 연산
  • 기본 타입 변수의 ==, != 연산은 변수의 값이 같은지 확인
  • 참조 타입 변수의 ==, != 연산은 동일한 객체를 참조하는지 확인

 

null 과 NullPointerException
  • 참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻으로 null 값을 가질 수 있다.
  • NullPointerException : 참조 타입 변수를 잘못 사용할 경우. null 을 가지고 있는 참조 타입 변수를 사용할 경우 발생.

 

배열 타입
  • 같은 타입의 데이터를 연속된 공간에 나열시키고, 각 데이터에 인덱스(index)를 부여해 놓은 자료구조
  • 인덱스는 0부터 시작
String[] names = {'a', 'b', 'c'};

names[0] -> a
names[1] -> b
names[2] -> c
  • new 연산자로 배열 생성
int[] intArray = new int[5];
  • 타입별 배열의 초기값

[타입별 배열의 초기값]

  • 배열의 길이 
int[] intArray = {10,20,30};
int num = intArray.length; //  배열의 길이

 

커맨드 라인 입력
  • "java 클래스"로 프로그램을 실행하면
  • JVM은 길이가 0인 String 배열을 먼저 생성하고 main() 메소드를 호출할 때 매개 값으로 전달한다.

[길이가 0인 String 배열]

  • "java 클래스 문자열0 문자열1 문자열2"으로 프로그램을 실행하면
  • 문자열 목록으로 구성된 String[] 배열이 생성되고 main() 메소드를 호출할 때 매개 값으로 전달된다.

[문자열 목록으로 구성된 String 배열]

  • Integer.parseInt() : 문자열은 산술 연산이 불가능 하기 때문에 메소드를 사용해서 정수로 변환시킨다.

 

다차원 배열
  • 1차원 배열과는 달리 행과 열로 구성된 배열을 2차원 배열이라고 한다.
int[][] scores = new int[2][3];

[2차원 배열의 메모리 구조]

배열 복사
  • System.arraycopy() 메소드 사용

 

열거 타입
  • 한정된 값만 갖는 데이터 타입
  • 몇 개의 열거 상수 중에서 하나의 상수를 저장하는 데이터 타입
  • 열거 타입 선언 
    • 열거 타입 이름을 정하고, 소스 파일(.java) 생성
    • 이름은 첫 문자를 대문자로 하고, 나머지를 소문자로 구성. 여러 단어로 구성된 경우 단어 첫 문자는 대문자로 구성.
    • public enum 열거타입이름 {...}
public enum Week {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, ...}
public enum LoginResult {LOGIN_SUCCESS, LOGIN_FAILED}

 

  • 열거 타입 변수
    • 열거타입 변수 = 열거타입.열거상수;
Week today = Week.SUNDAY;
Week birthday = null;

열거 객체의 메소드
  • name() : 열거 객체가 가지고 있는 문자열 리턴
  • ordinal() : 전체 열거 객체 중 몇 번째 열거 객체인지 알려준다.
  • compareTo() : 매개값으로 주어진 열거 객체를 기준으로 전후로 몇 번째 위치하는지 비교
  • valueOf() : 매개값으로 주어지는 문자열과 동일한 문자열을 가지는 열거 객체를 리턴
  • values() : 열거 타입의 모든 열거 객체들을 배열로 만들어 리턴

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA] 자바 메모리 구조 - Heap, Stack, JVM, GC  (0) 2022.06.23
Ch06. 클래스  (0) 2022.01.02
Ch04. 조건문과 반복문  (0) 2022.01.01
Ch03. 연산자  (0) 2022.01.01
Ch02. 변수와 타입  (0) 2022.01.01
제어문
  • 실행 흐름을 개발자가 원하는 방향으로 바꿀 수 있도록 해주는 것
  • 조건문 : if문, switch문
  • 반복문 : for문, while문, do-while문
    • 루핑(looping) : 반복문에서 제어문 처음으로 다시 되돌어가 반복 실행하는 것

 

조건문(if문, switch문)
  • if문, if-else문, if-else if-else문, 중첩 if문
  • switch문
    • if문처럼 조건식이 true인 경우 실행하는 것이 아닌, 변수의 값에 따라 실행문이 선택된다.
    • break가 없으면 값과는 상관없이 다음 case가 연달아 실행된다.

 

반복문(for문, while문, do-while문)
  • for문 : 반복 횟수를 알고 있을 경우
    • for(초기화식, 조건식, 증감식)
for(int i=1; i<=10; i++){
    System.out.println(i);
}
  • while문 : 조건에 따라 반복할 때 주로 사용
  • do-while문  
    • System.in.read() : 키보드의 키 코드를 읽는다.
int i = 1;
while (i<=10){
    System.out.println(i);
    i++;
}
  • continue문, break문 사용

'프로그래밍 > JAVA' 카테고리의 다른 글

Ch06. 클래스  (0) 2022.01.02
Ch05. 참조 타입  (0) 2022.01.01
Ch03. 연산자  (0) 2022.01.01
Ch02. 변수와 타입  (0) 2022.01.01
Ch01. 자바 시작하기  (0) 2022.01.01

+ Recent posts