Java 문법 정리

hee's 정리노트·2025년 3월 9일

Java

목록 보기
2/4

1. 변수와 자료형

  • 변수 : 데이터를 저장하기 위한 메모리 공간

  • 상수

    • 상수는 최초 초기화 후 값을 재정의 할 수 없음
    • static final 키워드 사용
  • 변수명 규칙

    • 대소문자 구분
    • 길이제한 없음
    • 숫자로 시작할 수 없음
    • 특수문자는 "_, $" 만 허용
    • 변수명에 공백 X
    • 예약어 사용 금지
  • 기본 자료형

    • 정수형 : byte, short, int, long
    • 실수형 : float, double
    • 논리형 : boolean
    • 문자형 : char (한 개로 이루어진 문자)
  • 래퍼런스 타입(Reference Type) : 자바에서 변수에 저장되는 값이 기본 자료형의 값이 아닌, 객체나 주소(참조)인 데이터 타입이며,실제 데이터는 힙(Heap) 메모리 공간에 저장된다.

    • String, Array, Class, Interface, Object, Enum, 사용자 정의 객체 등
    • 박싱 (boxing) : 기본 자료형의 값을 래퍼런스 타입으로 변환하는 과정
    • 언박싱 (unboxing) : 반대로 래퍼런스 타입을 기본 자료형으로 변환하는 과정
    • Java5 이후부터는 명시적으로 변환하지 않아도 자동 변환되는 오토박싱과 오토언박싱을 지원함
  • 기본 자료형과 래퍼런스 타입의 차이점

특징기본 자료형 (Primitive Types)래퍼런스 타입 (Reference Types)
저장 값값 자체객체의 메모리 주소 (참조)
메모리 위치스택 (Stack)힙 (Heap)
크기고정 크기객체 크기는 가변적, 참조는 일정 크기
값 변경다른 변수에 할당하면 값만 복사객체를 참조하면 값이 공유될 수 있음
예시int, boolean, char, floatString, Array, Object, Class

2. 연산자

  • 연산자 : 프로그램에서 연산을 위해 사용하는 기호를 연산자(Operator)라고 한다. 자바에서 사용하는 연산자(Operators)는 크게 산술 연산자, 비교 연산자, 논리 연산자, 대입 연산자, 비트 연산자 등 여러 종류로 나눌 수 있다

2-1. 산술 연산자 (Arithmetic Operators)

산술 연산자는 수학적인 계산을 수행할 때 사용된다.

연산자설명예시
+덧셈a + b
-뺄셈a - b
*곱셈a * b
/나눗셈a / b
%나머지(모듈러)a % b

2-2. 비교 연산자 (Comparison Operators)

비교 연산자는 두 값을 비교하고, 결과를 불리언 값 (true 또는 false)으로 반환한다.

연산자설명예시
==두 값이 같으면 true 반환a == b
!=두 값이 다르면 true 반환a != b
>왼쪽 값이 더 크면 truea > b
<왼쪽 값이 더 작으면 truea < b
>=왼쪽 값이 크거나 같으면 truea >= b
<=왼쪽 값이 작거나 같으면 truea <= b

2-3. 논리 연산자 (Logical Operators)

논리 연산자는 두 개 이상의 조건을 결합하여 결과를 true 또는 false로 반환한다.

연산자설명예시
&&AND 연산 (두 조건이 모두 true일 때 true)a > 0 && b < 10
``
!NOT 연산 (조건이 truefalse로, falsetrue로 바꿈)!a

2-4. 대입 연산자 (Assignment Operators)

대입 연산자는 변수에 값을 할당하는 데 사용된다.

연산자설명예시
=오른쪽 값을 왼쪽 변수에 할당a = b
+=더한 값을 대입a += b (a = a + b)
-=뺀 값을 대입a -= b (a = a - b)
*=곱한 값을 대입a *= b (a = a * b)
/=나눈 값을 대입a /= b (a = a / b)
%=나머지 값을 대입a %= b (a = a % b)

2-5. 비트 연산자 (Bitwise Operators)

비트 연산자는 이진수 단위로 비트 연산을 수행한다.

연산자설명예시
&비트 AND 연산a & b
``비트 OR 연산
^비트 XOR 연산a ^ b
~비트 NOT 연산 (비트 반전)~a
<<왼쪽으로 비트 시프트a << 2
>>오른쪽으로 비트 시프트a >> 2

2-6. 증감 연산자 (Increment and Decrement Operators)

증감 연산자는 변수를 1만큼 증가시키거나 감소시킬 때 사용된다.

연산자설명예시
++1만큼 증가 (후위/전위)a++, ++a
--1만큼 감소 (후위/전위)a--, --a

2-7. 삼항 연산자 (Ternary Operator)

삼항 연산자는 조건에 따라 두 값을 선택하는 간단한 조건문이다.

연산자설명예시
? :조건식이 true이면 첫 번째 값, false이면 두 번째 값 반환`a > b

3. 조건문

조건문은 프로그램의 흐름을 제어하고 특정 조건에 따라 다른 코드를 실행하게 해주는 구문을 말한다.

3-1. if문

if 문은 주어진 조건이 true일 때 특정 코드를 실행한다. 조건이 false일 경우에는 실행되지 않는다.

if (조건) {
    // 조건이 true일 때 실행되는 코드
}

3-2. else if 문

else if 문은 여러 개의 조건을 검사하고, 그 중 첫 번째로 참인 조건을 실행한다. 모든 조건이 거짓일 경우, else 블록이 실행된다.

if (조건1) {
    // 조건1이 true일 때 실행되는 코드
} else if (조건2) {
    // 조건2가 true일 때 실행되는 코드
} else {
    // 모든 조건이 false일 때 실행되는 코드
} 

3-3. switch 문

switch 문은 여러 가지 조건 중에서 하나를 선택하는데 유용한 조건문이다. switch 문은 조건이 여러 개일 때 더 깔끔하게 작성할 수 있다.

switch (변수) {
    case1:
        // 변수의 값이 값1일 때 실행되는 코드
        break;
    case2:
        // 변수의 값이 값2일 때 실행되는 코드
        break;
    default:
        // 변수의 값이 어떤 case와도 일치하지 않을 때 실행되는 코드
}

3-4. break, continue

  • break: 반복문에서 조건을 만족하면 즉시 반복을 종료하여 벗어난다.
  • continue: 반복문에서 조건을 만족하면 해당 반복을 건너뛰고 다음 반복으로 넘어간다.

4. 반복문

반복문은 특정 조건이 참일 동안 특정 코드 블록을 반복적으로 실행한다.

4-1. for 문

for문은 중복된 코드를 특정 횟수만큼 반복할 때 사용한다. (초기값, 조건값, 증감식)으로 구성되어 있다.

for (int i = 0; i < 5; i++) {
    System.out.println("i : " + i);
}

4-2. while 문

while문은 주어진 조건이 true일 때 계속 반복한다. 반복 전에 조건을 먼저 검사하고 조건이 false이면 반복문을 종료한다.

int i = 0;
while (i < 5) {
    System.out.println("i : " + i);
    i++;
}

4-3. do-while 문

do-while문은 반목문을 최소 한번 실행한 후 조건을 검사한다. 즉, 조건이 false일지라도 코드 블록이 한번은 실행된다.

int i = 0;
do {
    System.out.println("i의 값: " + i);
    i++;
} while (i < 5);

5. 배열

배열은 동일한 데이터 타입의 값을 여러 개 저장할 수 있는 데이터 구조이다. 자바에서 배열은 고정 크기를 가지며, 인덱스를 통해 배열의 각 요소에 접근할 수 있다.

5-1. 배열 선언

배열을 선언할 때는 배열의 데이터 타입을 먼저 지정하고, 그 뒤에 대괄호 []를 붙여 배열임을 명시합니다.

타입[] 배열명;
// ex
int[] numbers;
String[] names;

5-2. 배열 생성

배열의 크기는 생성시에 지정되며, 배열 크기는 고정되어 변경할 수 없다.

배열명 = new 타입[크기];
// ex
numbers = new int[5];  // 크기가 5인 정수형 배열 생성
names = new String[3]; // 크기가 3인 문자열 배열 생성

5-3. 배열 초기화

배열을 선언과 동시에 값을 초기화 할 수 있다. 배열을 초기화할 때는 대괄호 안에 값을 넣는다.

타입[] 배열명 = {1,2,3, ...};
// ex
int[] numbers = {1, 2, 3, 4, 5};  // 크기가 5인 배열 초기화
String[] names = {"John", "Jane", "Tom"};  // 크기가 3인 배열 초기화

5-4. 배열 값 접근

배열 값은 인덱스를 사용하여 접근한다. 배열의 인덱스는 0부터 시작한다.

int[] numbers = {1, 2, 3, 4, 5};
System.out.println(numbers[0]);  // 첫 번째 요소 출력 -> 1
System.out.println(numbers[3]);  // 네 번째 요소 출력 -> 4

5-5. 다차원 배열

타입[][] 배열명;
배열명 = new 타입[행의 수][열의 수];

// ex
int[][] matrix = new int[3][3];  // 3x3 배열 생성
matrix[0][0] = 1;  // 첫 번째 행 첫 번째 열에 값 1 할당
matrix[2][2] = 9;  // 세 번째 행 세 번째 열에 값 9 할당

6. 클래스 (Class)

객체를 생성하기 위한 설계도로 변수, 생성자와 메소드로 구성되어있다. 객체 지향 프로그래밍(OOP)의 기본 단위이며, 클래스를 사용하여 객체를 생성하고 해당 객체가 수행할 동작을 정의할 수 있다.

  • 클래스가 필요한 이유
    • 데이터 관리의 효율성
    • 코드의 재사용성
    • 데이터 보호 (캡슐화)
    • 코드의 구조화

6-1. 클래스 선언

클래스를 선언할 때는 class 키워드를 사용하여 클래스 이름 지정한다. 클래스 이름은 각 단어의 첫 글자를 대문자(파스칼 케이스)로 사용한다.

public class 클래스명 {
    // 필드 (변수)
    // 메서드
}

6-2. 클래스의 변수

  • 인스턴스 변수
    • 객체마다 가지는 고유한 값
    • 객체 생성 시에만 사용 가능
  • static 변수
    • 모든 객체가 공유하는 값
    • 객체 생성 없이도 사용 가능
  • 상수
    • 한 번 값이 정해지면 변경 불가능
    • 보통 static과 함께 사용

6-3. 생성자

  • 생성자
    • 객체가 생성될 때 자동으로 호출되는 특별한 메소드
    • 객체의 초기화를 담당
    • 클래스명과 동일한 이름을 가짐
  • 기본 생성자
    • 클래스에 생성자가 없으면 자동으로 생성
  • 매개변수가 있는 생성자
    • 객체 생성시 초기값을 전달 받음
public class Car {
    // 필드 (변수)
    
    // 1. 기본 생성자
    public Car() {}
    
    // 2. 매개변수가 있는 생성자
    public Car(String modelName, int price){
    this.modelName = modelName;
    this.price = price;
    }
}

6-4. 메소드

  • 인스턴스 메소드
    • 객체를 생성해야만 사용할 수 있는 메소드
  • static 메소드
    • 객체 생성 없이 클래스만으로도 호출 가능한 메소드
    • 인스턴스 변수를 사용할 수 없음
public class Car {
    String modelName;
    int price;
    
    // 1. 인스턴스 메소드
    void printPrice(String modelName, int price){
    	System.out.println(modelName + "의 가격은 " + price + "원 입니다".
    }
    // 2. static 메소드
    static void printPrice(String modelName, int price){
    	System.out.println(modelName + "의 가격은 " + price + "원 입니다".
    }
}

6-5. 객체 생성

클래스를 정의한 후 new 키워드를 사용하여 객체를 생성할 수 있다. 각 객체는 독립적인 메모리 공간을 가지면 같은 클래스로 만들어도 서로 다른 객체는 독립적이다.

클래스명 객체명 = new 클래스명();
// ex
Car myCar = new Car(); 

6-6. 접근제어자

6-6-1. 클래스의 접근제어자

클래스를 정의할 때 publicdeafult 두 가지 접근제어자를 사용할 수 있다.

  • public : public 을 사용하면, 모든 클래스에서 이 패키지 상관없이 클래스에 접근이 가능함
  • default : 같은 패키지 안에 클래스만 접근이 가능함

6-6-2. 클래스 멤버의 접근제어자

  • public 멤버 : 모든 클래스에서 접근 가능
  • private 멤버 : 같은 클래스안에 있는 멤버만 접근 가능
  • protected 멤버 : 같은 패키지 안의 멤버, 다른 패키지의 자식 클래스 멤버만 접근 가능
  • default 멤버 : 같은 패키지 안에 클래스 멤버만 접근이 가능함

7. 상속

부모 클래스의 기능을 자식 클래스가 물려받아 코드를 재사용하고 확장할 수 있는 개념이다. 객체지향의 핵심 기법으로 코드의 재사용성을 높이고 상속을 통해 클래스 간의 계층적 구조를 설계할 수 있다.

public class Animal {
}

public class Dog extends Animal{
}

7-1. super와 this 키워드

super 키워드를 통해 부모 클래스의 기능을 참조할 수 있다. 만약 생성자에서 호출할 때는 가장 먼저 호출해야한다.

public class Animal {
	Streing name;
    
    Animal(String name){
    	this.name = name;
    }
}

public class Dog extends Animal{
	String breed;
    
    Dog(String name, String breed){
    	super(name); // 부모 생성자 호출
        this.breed = breed;
    }
}

this 키워드는 자기 자신의 멤버(필드 , 메소드)를 참조할 때 사용한다.

public class Animal {
	Streing name;
    
    // 기본 생성자
    Animal(){
    	this("하늘이"); // 다른 생성자 호출
    }
    
    // 생성자
    Animal(String name){
    	this.name = name;
    }
}

7-2. 메소드 오버로딩 (Method Overloading)

메소드 오버로딩은 같은 클래스 내에서 같은 이름의 메소드를 여러 개 정의하는 것이다. 매개변수의 타입, 개수, 순서를 다르게 하여 구분할 수 있다.

class Calculator{
	int add(int a, int b){
    	return a + b;
    }
    double add(double a, double b){
    	return a + b;
    }
}

7-3. 메소드 오버라이딩 (Method Overriding)

메소드 오버라이딩은 부모 클래스의 메소드를 자식 클래스에서 재정의하는 것을 말한다. 부모의 메소드를 자식 클래스에 맞게 수정해서 사용한다.

public class Animal {
	void sound(){
    	System.out.println("동물 소리");
    }
}

public class Dog extends Animal{
	@Override
    void sound(){
    	System.out.println("멍멍!");
    }
}

8. 다형성 (Polymorphism)

다형성은 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 말한다. 다형성을 활용하면 부모 타입 참조 변수로 자식 객체를 참조할 수 있다.

  • 장점
    • 코드의 유연성 증가
    • 재사용성 향상
    • 유지보수 용이
public class Animal {
	void sound(){
    	System.out.println("동물 소리");
    }
}

public class Dog extends Animal{
	@Override
    void sound(){
    	System.out.println("멍멍!");
    }
}

public class Main{
	public static void main(String[] args){
    	Animal dog = new Dog(); // 개 객체를 동물 타입으로 참조
    }

8-1. 업캐스팅 (Upcasting)

객체의 업캐스팅은 자식 객체를 부모 타입으로 변환하는 것을 말한다. 업캐스팅은 자동으로 변환된다. (묵시적 형변환)

Animal dog = new Dog(); 

8-2. 다운캐스팅 (Downcasting)

객체의 다운캐스팅은 부모 타입을 자식 타입으로 변환하는 것을 말한다. 이 경우에는 명시적 형변환이 필요하다.

Animal animal = new Dog(); 
Dog dog = (Dog) animal;

9. 추상 클래스 (Abstract Class)

  • 추상은 객체의 공통 특징이나 속성을 추출하는 개념을 말한다.
  • 추상화하는 과정은 복잡한 것을 단순화 하는 것이라고 볼 수 있다.
  • 추상 클래스는 abstract 키우더를 사용해 생성할 수있다.
  • 내부에는 생성자, 필드, 일반 메소드, 추상 메소드가 포함될 수 있다.
  • new 연산자로 객체를 생성할 수 없으며 자식 클래스에서 추상 클래스의 기능을 필수로 구현해야 한다.

9-1. 추상 메소드

  • 추상 메소드는 추상 클래스를 상속 받은 자식 클래스가 필수로 구현해야하는 메소드이다.
  • 공통 동작은 추상 클래스에서 직접 구현하며, 자식 클래스마다 세부 구현이 달라질 수 있으면 추상 메소드로 선언한다.

10. 인터페이스 (Interface)

객체의 동작을 표준화하는 기법을 인터페이스라고 한다. 추상 메소드와 상수만 가질 수 있다. interface 키워드로 인터페이스를 만들고 구현 클래스에 implements 키워드로 구현하고 싶은 인터페이스를 선언한다.

인터페이스를 사용하는 이유

  • 표준화
    - 개발에 필요한 기본 틀 제공
    • 개발자들 간의 일관성 있는 개발 가능
  • 다형성 구현
    - 하나의 인터페이스로 다양한 구현이 가능
    • 객체 교체가 쉬움
  • 개발 독립성
    - 인터페이스만 정의되면 개발 시작 가능
    • 다른 팀/개발자와 동시 개발 가능
  • 유연성
    - 기존 코드 변경 없이 새로운 기능 추가 가능
    • 독립적인 기능 구현 가능
public interface 인터페이스 이름{
	// 상수
    // 추상 메소드
    // default 메소드
}

0개의 댓글