객체 지향 프로그래밍
  • 객체들을 먼저 만들고, 이것들을 하나씩 조립해서 완성된 프로그램을 만드는 기법
  • 객체(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
연산자와 연산식
  • 연산(operations) : 프로그램에서 데이터를 처리하여 결과를 산출하는 것
  • 연산자(operator) : 연산에 사용되는 표시나 기호
  • 피연산자(operand) : 연산되는 데이터
  • 연산식(expressions) : 연산자와 피연산자를 이용한 연산 과정을 기술한 것

[연산자 종류]

  • 단항, 이항, 삼항 연산자 순으로 우선순위를 가진다.
  • 산술, 비교, 논리, 대입 연산자 순으로 우선순위를 가진다.
  • 단항과 대입 연산자를 제외한 모든 연산의 방향은 왼쪽에서 오른쪽이다.
  • 복잡한 연산식에는 괄호()를 사용해서 우선순위를 정해준다.

[연산자 우선순위]

  • 부호 연산자의 결과는 int 타입이므로, 결과를 산출하는 데이터의 타입을 int 형으로 바꾸어야 한다.
  • ++i 의 속도는 i=i+1 보다 연산 속도가 빠르다.
    • 후자는 = 연산자, + 연산자의 총 두 번의 연산이 필요하다.
    • 전자는 ++ 하나의 연산만 수행한다.
    • 하지만 실제로 컴파일하면 동일한 바이트 코드가 생성된다. 때문에 둘 중 어떤 것이 연산 속도가 빠르다고 볼 수는 없다.
  • 비트 반전 연산자(~)의 결과는 int 타입이므로, 결과를 산출하는 데이터 타입을 int 형으로 바꾸어야 한다.
  • Integer.toBinaryString() : 정수 값을 총 32비트의 이진 문자열로 리턴하는 메소드 
  • long 타입을 제외한 정수의 산술 연산은 무조건 int 타입으로 변환 후 연산을 수행한다. 그 이유로는 JVM이 기본적으로 32비트 단위의 계산을 하기 때문이다.
  • 산술 연산을 하기 전에 피연산자들의 값을 조사해서 오버플로우를 방지하자. 프로그램 실행 도중 예외가 발생하면 실행이 멈추고 프로그램이 종료된다. 이러한 경우 예외 처리를 해야 한다.
  • Nan & Infinity 연산 
    • 아래의 메소드를 사용해 Infinity와 NaN이 산출되면, 다음 연산을 수행하지 않는다. 
    • Double.isInfinite() 메소드 사용
    • Double.isNan() 메소드 사용
  • String 타입의 문자열 비교
    • strVar1, strVar2 동일한 String 객체의 번지수
    • strVar3 객체 생성 연산자인 new로 생성한 새로운 String 객체의 번지수
    • ==  연산자는 변수에 저장된 값만 비교한다. -> equals() 메소드 사용

[서로 다른 객체의 번지 값]

String strVar1 = "ABC";
String strVar2 = "ABC";
String strVar3 = new String("ABC");

System.out.println( strVar1 == strVar2);    // true
System.out.println( strVar1 == strVar3);    // false

System.out.println( strVar1.equals(strVar2));   // true
System.out.println( strVar1.equals(strVar3));   // true

 

  • 비트 연산자
    • 데이터를 bit 단위로 연산한다.
    • 정수 타입만 비트 연산이 가능하다.
    • 비트 논리 연산자(&, |, ^, ~) 
    • 비트 이동 연산자(<<, >>, >>>)

[비트 이동 연산자]

 

  • 삼항 연산자
    • 세개의 피연산자를 필요로 하는 연산자
    • ? 앞의 조건식에 따라 콜론(:) 앞 뒤의 피연산자가 선택된다고 해서 조건 연산식이라고 부르기도 한다.
    • 조건식 ? 값 또는 연산식(true) : 값 또는 연산식(false)
public class ConditionalOperationExample {
    public static void main(String[] args){
        int score = 85;
        char grade = (score > 90) ? 'A' : ((score > 80) ? 'B' : 'C');
        // 첫 번째 조건에서 90보다 작기 때문에 score > 80 으로 이동
        // 두 번째 조건에서 80보다 크기 때문에 'B'의 값을 얻게 된다. 
        System.out.println(score + "점은 " + grade + "등급입니다.");
    }
}

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

Ch06. 클래스  (0) 2022.01.02
Ch05. 참조 타입  (0) 2022.01.01
Ch04. 조건문과 반복문  (0) 2022.01.01
Ch02. 변수와 타입  (0) 2022.01.01
Ch01. 자바 시작하기  (0) 2022.01.01
변수 (Variable)
  • 값을 저장할 수 있는 메모리의 공간
  • 프로그램에 의해서 수시로 값이 변동될 수 있다.
  • 하나의 타입, 하나의 값만 저장이 가능하다.

 

변수명 작성 규칙
  • 첫 번째 글자는 문자이거나 '&', '_' 이어야 한다. 숫자 불가능
  • 영어 대소문자 구분
  • 첫 문자는 영어 소문자로 시작, 다른 단어가 붙을 경우 첫 문자를 대문자로
  • 문자 수 길이의 제한 X
  • 예약어 사용 불가능

 

예약어 

[자바의 예약어]&nbsp;

 

리터럴 (literal)
  • 소스 코드 내에서 직접 입력된 값을 리터럴 이라고 부른다.
  • 정수 리터럴, 실수 리터럴, 문자 리터럴, 논리 리터럴

 

정수 리터럴 - byte, char, short, int, long
  • 10진수 : 소수점이 없는 정수 리터럴 
    • 0, 75, -100
  • 8진수 : 0으로 시작되는 리터럴 
    • 02, -04
  • 16진수 : 0x 또는 0X로 시작하고 0~9 숫자나 A~F 또는 a~f로 구성된 리터럴
    • 0x5, 0xA, 0xB3, 0xAC08

 

실수 리터럴 - float, double
  • 10진수 : 소수점이 있는 리터럴
    • 0.25, -3.14
  • 10진수 지수와 가수 : 대문자 E 또는 소문자 e 가 있는 리터럴 
    • 5E7(5x10^7), 0.12E-5(0.12x10^-5)

 

문자 리터럴 - char
  • 작은 따옴표(')로 묶은 텍스트를 하나의 문자 리터럴로 간주한다.
    • 'A', '한', '\t', '\n'

 

문자열 리터럴 - String
  • 큰 따옴표(")로 묶은 텍스트는 문자열 리터럴로 간주한다.
    • "대한민국", "탭 만큼 이동 \t 합니다."

 

논리 리터럴 - boolean
  • true / false

 

이스케이프 문자 
  • 이스케이프(escape) : 역슬래쉬( \ ) 가 붙은 문자 리터럴

[이스케이프 문자 종류]

 

변수의 사용 범위
  • 로컬 변수(local variable) : 메소드 블록 내에서 선언된 변수. 메소드 실행이 끝나면 메모리에서 자동으로 없어진다.
  • 변수는 선언된 블록 내에서만 사용 가능
  • 메소드 블록 첫머리에 선언 권장

 

데이터 타입
  • 기본 타입(primitive) : 정수, 실수, 문자, 논리 리터럴을 직접 저장하는 타입
  • 비트(bit) : 최소 기억 단위
    • 8 bit = 1 byte

[데이터 기본 타입의 메모리의 크기와 저장되는 값의 범위]

 

  • 정수 타입(byte, char, short, int, long) 
    • 자바의 기본 정수 연산 Int
    • byte와 short는 범위를 초과할 수 있는 위험이 있다.
    • 최소값과 최대값을 넘으면 최소값부터 다시 시작한다. 
      • ex) byte ~128에서 127일 경우, -128 부터 시작

[byte(var1), int(var2) 타입 예시]

 

  • char 타입
    • 자바는 모든 문자를 유니코드(Unicode)로 처리한다.
    • char 타입 변수를 int 타입에 저장하면 유니코드를 알 수 있다.
    • char c = ''; 컴파일 에러 -> char c = ' ';
    • String str = ""; 은 가능하다.
public class unicode {
    public static void main(String[] args){
        char c1 = 'A';      // 문자 직접 저장 -> A
        char c2 = 65;       // 10진수로 저장 -> A
        char c3 = '\u0041';     // 16진수로 저장 -> A

        char c4 = '가';      // 문자 직접 저장 -> 가 
        char c5 = 44032;        // 10진수로 저장 -> 가
        char c6 = '\uac00';     // 16진수로 저장 -> 가

        int uniCode = c1; 
        // 유니코드 얻기 -> 65
        // char 타입 변수를 int 타입 변수에 저장한다.

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(uniCode);
    }
}

 

  • short 타입 
    • C 언어와의 호환을 위해 사용되며, 비교적 자바에서는 잘 사용되지 않는다.
  • int 타입 
    • byte, short 타입과 성능 차이는 거의 없기 때문에, 메모리가 크게 부족하지 않은 경우 int 타입을 사용한다.
    • 8진수 : '0' 
    • 16진수 : '0x'
    • 변수에 어떤 진수로 입력을 해도 2진수로 변환되어 저장된다.
  • long 타입 
    • 변수를 초기화할 때에는 정수값 뒤에 소문자 'l'이나 대문자 'L'을 붙일 수 있다.
    • 컴파일러에게 4byte가 아닌 8byte 정수 데이터를 알려주기 위한 목적
public class LongExample {
    public static void main(String[] args){
        long var1 = 10;
        long var2 = 20L;
        // long var3 = 10000000000000; 컴파일 에러
        long var4 = 10000000000000L;

        System.out.println(var1);
        System.out.println(var2);
        System.out.println(var4);
    }
}

 

  • 실수 타입(float, double)
    • 정수와 다르게 부동 소수점(floating-point) 방식으로 저장
    • 가수와 지수를 저장하기 위해 전체 bit를 나누어 사용
    • 가수 : 0 <= m < 1
    • 자바는 실수 리터럴의 기본 타입을 dobule으로 간주
    • float 타입으로 저장하려면 소문자 'f'나 대문자 'F'를 붙인다.

[부동 소수점 방식]
[실수형 타입의 bit 사용 방법]

 

  • 논리 타입(boolean)
    • 상태 값에 따라 조건문과 제어문의 실행 흐름을 변경하는데 주로 사용
    • true / false

 

타입 변환
  • 자동(묵시적) 타입 변환
    • 프로그램 실행 도중에 자동으로 타입 변환.
    • 작은 크기를 가지는 타입이 큰 크기를 가지는 타입에 저장될 때 발생
    • 단 하나의 예외로는, char 범위는 0~65535 이므로, 음수가 저장될 수 없기 때문에 음수 byte -> char 은 불가능
  • 강제(명시적) 타입 변환 = 캐스팅(Casting)
    • 큰 데이터 타입을 작은 데이터 타입으로 쪼개어서 저장하는 방법
    • 원래 int 값은 보존되지 않지만, int 값이 끝 1 byte 으로만 표현이 가능하다면, 값은 유지될 수 있다.
    • 자동 변환 되지 않는 경우
      1. int -> char 
      2. 실수(float, double) -> 정수(byte, short, int, long) : 소수점은 버려지고, 정수 부분만 저장
int intValue = 1030299770;
byte byteValue = (byte) intValue; // 강제 타입 변환(캐스팅)

[기본 타입 별 최대값, 최소값 상수]

 

  • 서로 다른 타입의 피연산자의 계산은 두 피연산자 중 크기가 큰 타입으로 자동 변환된 후 연산을 수행한다.

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

Ch06. 클래스  (0) 2022.01.02
Ch05. 참조 타입  (0) 2022.01.01
Ch04. 조건문과 반복문  (0) 2022.01.01
Ch03. 연산자  (0) 2022.01.01
Ch01. 자바 시작하기  (0) 2022.01.01

앞으로 자바 개념부터 정리해보려고 한다.

자료는 '이것이 자바다' 책을 기반으로 정리해보았다.  

 

프로그래밍 언어란?
  • 저급 언어 : 기계어, 어셈블리어
  • 고급 언어 : 프로그래밍 언어(C, C++, JAVA)
  • 컴파일 : 고급 언어를 컴퓨터가 이해할 수 있는 기게어로 변환하는 과정
  • 프로그램 : 컴퓨터에서 특정 목적을 수행하기 위해 프로그래밍 언어로 작성된 소스를 기계어로 번역한 것

 

자바란?
  • 1995~1999년 : 메모리 및 CPU를 지나치게 많이 사용하기 때문에 윈도우 프로그래밍 언어로는 부적합
  • 1999년 : 인터넷의 활성화로 웹 애플리케이션 구축용 언어로 자바의 급부상
  • 다양한 서버 운영 체제에서 단 한번의 작성으로 모든 곳에서 실행 가능한 언어였다.

 

자바의 특징
  • 이식성이 높은 언어 : JRE(Java Runtime Environment)가 설치되어 있는 모든 운영체제에서 실행 가능하다.
  • 객체 지향 언어 : 부품에 해당하는 객체를 먼저 만들고, 하나씩 조립 및 연결해서 전체 프로그램을 완성하는 기법을 OOP라고 한다. 자바는 객체를 고려하여 설계되었기 때문에 객체지향 언어가 가져야 하는 특징인 캡슐화, 상속, 다형성 기능을 완벽하게 지원한다.
  • 함수적 스타일 코딩 지원 : 대용량 데이터의 병렬 처리 그리고 이벤트 지향 프로그래밍을 위해 적합하다. 함수적 프로그래밍을 위해 람다식을 지원한다. 람다식은 컬렉션의 요소를 필터링, 매핑, 집계 처리하는데 쉬워지고, 코드가 매우 간결해진다.
  • 메모리를 자동 관리 : C++은 메모리에 생성된 객체를 제거하려면 개발자가 직접 코드를 작성. 자바는 개발자가 직접 메모리에 접근할 수 없도록 설계되었고, 메모리는 자바가 관리한다. 사용이 완료되면, Garbage Collector를 실행시켜 사용하지 않는 객체를 제거한다.
  • 다양한 애플리케이션을 개발 가능 : 자바는 다양한 운영체제에서 사용할 수 있는 개발 도구와 API를 묶어 에디션(Edition) 형태로 정의한다.
    • JAVA SE(Standard Edition)는 JVM를 비롯한 도구와 라이브러리 API를 정의한다. 
    • JAVA EE(Enterprise Edition)는 분산환경에서 서버용 애플리케이션(Servlet/JSP, EJB, Web Services)을 개발하기 위한 도구 및 라이브러리 API를 정의한다.
  • 멀티 스레드(Multi-Thread)를 쉽게 구현 : 하나의 프로그램이 동시에 여러 가지 작업을 처리해야 하는 경우와 대용량 작업을 빨리 처리하기 위해 서브 작업으로 분리해서 병렬 처리하려면 멀티 스레드 프로그래밍이 필요하다. 운영체제마다 멀티 스레드의 구현 방법이 다르지만, 자바는 관련 API를 이용해 멀티 스레드를 쉽게 구현할 수 있다.
  • 동적 로딩 지원(Dynamic Loading) 지원 :  애플리케이션이 실행될 때 모든 객체가 생성되지 않고, 객체가 필요한 시점에 클래스를 동적 로딩해서 객체를 생성한다. 따라서 유지보수가 쉽고 빠르다.
  • 오픈소스 라이브러리 풍부 : 자바는 오픈소스 언어이다. 검증된 오픈소스 라이브러리를 사용하면, 개발 기간의 단축과 안전성 확보가 가능하다.

 

자바 가상 기계(JVM)
  • 자바 프로그램은 중간 단계의 바이트 코드이기 때문에 이것을 해석하고 실행할 수 있는 가상의 운영체제가 필요하다. 이것을 JVM 이라고 한다. 
  • 운영체제마다 프로그램을 실행하고 관리하는 방법이 다르기 때문에 운영체제와 자바 프로그램을 중계하는 JVM을 두어 자바 프로그램이 여러 운영체제에서 동일한 실행 결과가 나오도록 설계한 것이다. 
  • 바이트 코드는 모든 JVM에서 동일한 실행 결과가 나오지만, JVM은 운영체제에 종속적이다.
  • JVM은 JDK 또는 JRE를 설치하면 자동으로 설치된다. 

[운영체제와 JVM 자바 프로그램의 실행 단계]

  1. .java 파일(소스 파일) 작성
  2. 소스 파일을 컴파일러로(javac.exe) 컴파일
  3. 확장자가 .class인 바이트 코드 생성
  4. 바이트 코드 파일은 JVM 구동 명령어(java.exe)에 의해 JVM에서 기계어로 해석되고 이 결과는 운영체제에 따라 달라진다.

 

자바 개발 도구 (JDK) 설치
  • JAVA SE(Standard Edition)의 구현체인 JDK를 먼저 설치해야 한다.
  • JAVA SE의 구현체는 JDK와 JRE 이라는 두 가지 버전이 있다.
    • JDK : 프로그램 개발에 필요한 JVM, 라이브러리 API, 컴파일러 등의 개발 도구 포함
    • JRE : 프로그램 실행에 필요한 JVM, 라이브러리 API 포함
  • JDK 내부의 bin 디렉토리는 컴파일러인 javac.exe와 JVM 구동 명령어인 java.exe를 포함
  • 이 명령어들을 다른 디렉토리에도 쉽게 실행할 수 있도록 Path 환경 변수에 bin 위치를 등록한다.

 

자바 프로그램 소스 작성부터 실행
  1. 소스 파일 생성(.java 텍스트 파일)
  2. 소스 파일을 컴파일러(javac.exe)로 컴파일
  3. 컴파일러로 바이트 코드(.class) 생성
  4. JVM 구동 명령어(java.exe)로 실행 // javac Hello.java -> Hello.class 파일 생성

[자바 프로그램 개발 순서 1]
[자바 프로그램 개발 순서 2]

 

프로그램 소스 분석
  • 클래스(class) 블록 : 필드 또는 메소드를 포함하는 블록
  • 메소드(method) 블록 : 어떤 일을 처리하는 실행문들을 모아 놓은 블록. 단독 작성 불가능. 클래스 블록 내부에 작성해야 한다.
    • main() 메소드 : 프로그램 실행 진입점(entry point)

 

추가 정리
  • 자바 소스 파일은 src 디렉토리에 저장
  • 바이트 코드 파일은 bin 디렉토리에 저장

 

 

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

Ch06. 클래스  (0) 2022.01.02
Ch05. 참조 타입  (0) 2022.01.01
Ch04. 조건문과 반복문  (0) 2022.01.01
Ch03. 연산자  (0) 2022.01.01
Ch02. 변수와 타입  (0) 2022.01.01

+ Recent posts