[Java] 자바 기초 문법

2024. 9. 22. 16:16·☕ Java

자바의 세계로 들어가기 전에 반드시 알아야 할 필수 문법입니다. 

 


1️⃣ 타입 

자바는 데이터를 저장할 때 타입을 반드시 선언합니다. 타입은 데이터의 종류를 정의하며, 변수에 저장할 수 있는 값의 형태를 제한합니다. 

 

  타입 변수 = 값;

boolean flag = true;

int year = 2024;
int month = 5;
double pi = 3.141592653;

char c = 'H';
char c2 = 65; // A 출력
String str = "Hello";

 

1. 기본 타입

값의 분류 기본 타입
정수 byte, char, short, int, long
실수 float, double
논리 (true/false) boolean

 

기본 타입은 값을 직접 저장하는 타입입니다. 정수, 실수, 논리값, 문자를 저장할 수 있습니다. 

(*`char`은 문자를 표현하는 데 사용되지만 정수형 데이터로 처리, 각 문자는 유니코드 값으로 매핑된다)

구분 타입 종류 선언 방법 저장 범위 메모리 크기
정수 byte byte b = 100; -128 ~ 127 1byte 8bit
char char c = 'A'; \u0000 ~ \uffff (유니코드) 2byte 16bit
short short s = 100; -32,768 ~ 32,767 2byte 16bit
int int i = 100; -2,147,483,648 ~ 2,147,483,647 4byte 32bit
long long l1 = 100L;
long l2 = 200L;
-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

* 값 뒤에 L 또는 l을 붙일 수 있지만, 소문자 l은 숫자 1과 혼동될 수 있으므로 대문자 L을 권장한다 
8byte 64bit
실수 float float f1 = 10.234F;
float f2 = 10.234f;
1.4 x 10^-45 ~ 3.4 x 10^38

*유효 소수 이하 자리는 약 7자리, 값 뒤에 F 또는 f를 붙인다
4byte 32bit
double double d = 10.211; 4.9 x 10^-324  ~ 1.8 x 10^308

*유효 소수 이하 자리는 약 15자리
8byte 64bit
논리 boolean boolean flag = true; 참이면 true, 거짓이면 false    

 

2. 참조 타입

객체의 번지를 참조하는 타입으로 배열, 열거, 클래스, 인터페이스 타입이 존재합니다.

💡 문자열(String)은 참조 타입이지만, 기본 타입처럼 사용한다. 

 

🔵 참조 타입의 특징

1. 스택 메모리에 값 대신 주소를 저장한다. 즉, 실제 데이터를 저장하는 것이 아니라, 데이터를 저장한 객체의 참조값(주소)를 저장한다.

2. 객체를 힙 메모리에 저장한다. 

3. new를 이용하여 객체를 생성한 후 사용한다. 타입을 선언하고 값을 스택 메모리에 바로 저장하는 기본 타입과는 다르다.

Geo geol = new Geo();
geol.latitude = 37.5;
geol.longitude = 127.0;

 

📌 메모리 영역 (메소드, 힙, 스택)

더보기

메소드 영역

바이트코드 파일을 읽은 내용이 저장되는 영역

 

힙 영역

동적 메모리 할당에 사용되는 영역으로, 프로그램 실행 중에 런타임에 필요한 객체들을 저장하는 공간이다. 주로 객체를 생성하거나 배열과 같은 데이터 구조를 사용할 때 사용된다. 힙 메모리에 할당된 데이터는 GC(Garbage Collector)에 의해 관리되며, 더 이상 참조되지 않는 객체들은 자동으로 해제된다.

 

스택 영역

주로 메서드 호출과 관련된 데이터를 저장하는데 사용되며 선입선출(FILO, First In Last Out)의 구조로 작동한다. 함수가 끝나면 메모리에서 자동으로 제거된다.

 

1) 배열(Array) 타입

 

✅ 배열 생성

// 1. 배열을 선언하면서 동시에 초기화
int[] num1 = {1, 2, 3, 4, 5};

// num1 = {1, 2}; // ❌ 다시 생성 불가능 (컴파일 에러 발생)
// num1 = {4, 5, 6, 7, 8}; // ❌ 다시 초기화 불가능

num1 = new int[] {1, 2}; // ⭕ new 키워드를 사용하는 경우에는 가능 (새로운 배열 할당)

// 2. 배열을 선언한 후 나중에 초기화
int[] num2 = new int[5]; // 길이가 5인 배열 생성 (초기값: 0)
num2[0] = -1; // 배열 요소 값 변경 가능 (배열은 가변 객체)

// num2 배열을 새로운 크기의 배열로 변경
num2 = new int[4]; // ⭕ 다시 생성 가능 (기존 배열은 GC에 의해 제거됨)

// new 키워드를 사용하여 새로운 배열로 다시 초기화
num2 = new int[] {1, 2, 3, 4, 5}; // ⭕ 다시 초기화 가능

💡 new 연산자로 배열을 처음 생성하면 배열 항목은 기본값으로 초기화됩니다. (정수 배열은 0, 실수 배열은 0.0, 논리 배열은 false, 참조 배열은 null)

 

✅ 다차원 배열 생성

// 1. 2차원 배열 선언과 동시에 초기화
int[][] matrix1 = { // 3x3 배열
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// 2. 2차원 배열을 선언한 후 초기화
int[][] matrix2 = new int[2][3]; // 2x3 배열 (초기값: 0)
matrix2[0][0] = 1;

// 3. 3차원 배열 선언과 동시에 초기화
int[][][] cube1 = { // 2x2x2 배열
    {
        {1, 2},
        {3, 4}
    },
    {
        {5, 6},
        {7, 8}
    }
};

// 4. 3차원 배열을 선언한 후 초기화
int[][][] cube2 = new int[2][2][2]; // 2x2x2 배열 (초기값: 0)
cube2[0][0][0] = 1;

 

✅ 배열 복사

import java.util.Arrays;

public class ArrayCopyExample {
    public static void main(String[] args) {
        int[] original = {1, 2, 3, 4, 5};

        // 1. for문을 사용한 배열 복사
        int[] copy1 = new int[original.length];
        for (int i = 0; i < original.length; i++) {
            copy1[i] = original[i];
        }

        // 2. System.arraycopy()를 사용한 배열 복사
        int[] copy2 = new int[original.length];
        System.arraycopy(original, 0, copy2, 0, original.length);

        // 3. clone() 메서드를 사용한 배열 복사
        int[] copy3 = original.clone();

        // 4. Arrays.copyOf()를 사용한 배열 복사
        int[] copy4 = Arrays.copyOf(original, original.length);
    }
}

 

2) 열거(Enum) 타입

한정된 값을 갖는 데이터입니다. 요일(월, 화, 수, 목, 금, 토, 일)이나 계절(봄, 여름, 가을, 겨울)이 열거 타입 데이터에 해당됩니다.

enum Day {
    MONDAY("월요일"),
    TUESDAY("화요일"),
    WEDNESDAY("수요일"),
    THURSDAY("목요일"),
    FRIDAY("금요일"),
    SATURDAY("토요일"),
    SUNDAY("일요일");

    private String koreanDay;

    // 생성자
    Day(String koreanDay) {
        this.koreanDay = koreanDay;
    }

    // 메서드
    public String getKoreanDay() {
        return koreanDay;
    }
}

public class EnumExample {
    public static void main(String[] args) {
        Day today = Day.MONDAY;

        System.out.println("오늘은 " + today.getKoreanDay() + "입니다.");
    }
}

 

3) 클래스(Class)

클래스는 객체를 생성하기 위한 틀(설계도)로, 필드(변수)와 메서드(기능)로 구성됩니다. `new` 키워드를 사용하여 객체를 생성하며, 사용자가 원하는 데이터와 기능을 하나의 단위로 묶어서 관리할 수 있습니다.

 

✅ 클래스 예제

class Car {
    String model;
    int year;

    void drive() {
        System.out.println(model + "가 달립니다.");
    }
}

 

a. 문자열(String) 타입

String은 기본 타입처럼 사용할 수 있는 특별한 클래스로, 문자열을 저장하고 조작하는 기능을 제공합니다. 특징적인 점은 한 번 생성된 문자열은 변경할 수 없는(Immutable) 객체라는 것입니다. 또한, new 키워드를 사용하지 않아도 문자열을 생성할 수 있습니다. 문자열을 다양한 방식으로 활용하는 방법을 예제와 함께 알아보겠습니다.

 

✅ 문자열의 생성

// 문자열 리터럴이 동일하므로 String 객체를 공유: 동일한 String 객체의 번지 저장
String name1 = "홍길동";
String name2 = "홍길동";

// name1과 name2는 같은 객체를 참조
// == 비교시 true를 반환
System.out.println(name1 == name2);  // true

// new 연산자를 사용해 새로운 객체 생성: 서로 다른 String 객체의 번지 저장
String name3 = new String("홍길동");
String name4 = new String("홍길동");

// name3과 name4는 서로 다른 객체를 참조
// == 비교시 false를 반환
System.out.println(name3 == name4);  // false

 

✅ 문자열의 불변성(Immutable)

String str = "Java";
str = str + " Programming";  // 기존 문자열이 변경되는 것이 아니라, 새로운 문자열이 생성됨
System.out.println(str);  // Java Programming (원본 문자열은 변하지 않음)

 

✅ 다양한 활용

String str = "Hello Java"

// 문자열 추출
char c = str.charAt(3); // 'l'

// 문자열 길이
int length = str.length(); // 10

// 문자열 대체
String newStr = str.replace("Java", "자바"); // "Hello 자바"

// 문자열 잘라내기
String ssn = "010329-3234567";
String firstNum = ssn.substring(0,6); // 010329
String secondNum = ssn.substring(7); // 1234567

// 문자열 찾기
int index = str.indexOf("Java"); // 6
int index2 = str.indexOf("자바"); // 포함되어 있지 않으므로 -1 

// 문자열 포함여부 확인
boolean result = str.contains("Hello"); // true

// 문자열 분리
String board = "사과,포도,바나나,딸기";
String[] arr = board.split(","); // {사과, 포도, 바나나, 딸기}

 

4) 인터페이스

클래스가 따라야 할 메서드의 규약(틀) 을 정의한 것으로, `interface` 키워드를 사용하여 선언합니다. 인터페이스에는 메서드의 선언만 존재하고, 실제 구현(몸체)은 없으므로 이를 구현하려면 `implements` 키워드를 사용하여 클래스에서 해당 메서드를 정의해야 합니다.

interface Animal {
    void sound();
}
class Dog implements Animal {
    public void sound() {
        System.out.println("멍멍");
    }
}

 

3. 타입 변환 (형 변환)

작은 타입은 큰 타입으로 자동 변환되지만, 큰 타입을 작은 타입으로 변환할 때는 (변환하려는 타입) 형식으로 타입 변환해서 사용합니다. 

📌 허용 범위 순
byte < short, char < int < long < float < double
💡 큰 허용 범위 타입 = 작은 허용 범위 타입 (👉🏻자동 타입 변환)
// 📌 자동 타입 변환

// byte 타입이 int 타입으로 자동 변환되는 경우
byte byteValue = 10;
int intValue = byteValue;

// char 타입이 int 타입으로 자동 변환되는 경우 -> 유니코드 값이 int 타입에 대입됨
char charValue = 'A';
int charToInt = charValue; // 65 (유니코드 값)

// 💡 예외: byte 타입은 char 타입으로 자동 변환될 수 없음 (char는 음수 X)

// 📌 강제 타입 변환

// 실수를 정수로 변환
double d = 3.14192;
int i = (int) d; // (변환하려는 타입)
int random = (int) (Math.random() * 45); // Math.random()은 0.0 <= x < 1.0 사이의 임의의 실수 반환

// 숫자형 문자를 정수로 변환
int num = '8' - '0'; // 56 - 48 = 8, ASCII 참고
int a = Character.getNumericValue('9'); // 9
int b = Character.digit('9', 10); // 9 

// ASCII를 숫자로 변환
int alpha = 'A'; // 65
char cAlpha = (char) 97; // 'a' -> (int) 'a' = 97

// 정수 연산은 결과도 정수
int x = 90;
int y = 95;
int z = 98;
int average = (x + y + z) / 3; // 실제 결과는 94.33이지만 정수 94를 반환

// 화씨를 섭씨로 변환 
public static double toCelsius(double fahrenheit) {  
    return 5.0 / 9 * (fahrenheit - 32);
}

// 현재 시간 (밀리초 → 일 변환)
long days = System.currentTimeMillis() / 1000 / 60 / 60 / 24;
int day = (int) days;

// 💡 상수 선언 (static final 사용)
public class SwitchMain {
    public static final int MATH = 83;  // 수학 점수
    public static final int KOR = 94;   // 국어 점수
}

 

 

⭐ 문자열 → 기본 타입의 변환

변환 타입 예시
String →  byte byte value = Byte.parseByte("문자열");
String → short short value = Short.parseShort("문자열");
String → int int value = Integer.parseInt("문자열");
String → long long value = Long.parseLong("문자열");
String → float float value = Float .parseFloat ("문자열");
String → double double value = Double.parseDouble("문자열");
String → boolean boolean value = Boolean.parseBoolean("문자열");

*기본 타입 → 문자열의 변환: String.valueOf("기본타입값")

 

 


2️⃣ 제어문

프로그램은 기본적으로 위에서 아래로 순차적으로 실행되지만, 상황에 따라 흐름을 제어해야 합니다. 제어문을 사용하여 프로그램의 흐름을 변경할 수 있으며, 이를 활용해 다양한 알고리즘을 구현할 수 있습니다.

1. 조건문

1) if문

if (조건식) { 조건문1 }
if (조건식) { 조건문1 } else { 조건문2 }
if (조건식1) { 조건문1 } else if (조건식2) { 조건문2 } else { 조건문3 }

 

조건식에서 동일 여부나 대소 비교를 합니다.

조건식이 true이면 조건문1 구문이 실행되고 조건식이 false이면 (else가 있을 경우) 조건문2 구문이 실행됩니다. else if의 경우에는 여러 개 사용할 수 있습니다.

int v = 100;

if (v % 2 == 0) {
    System.out.println("짝수");
} else {
    System.out.println("홀수");
}

// 삼항 연산자로 표현 가능
String answer = (v % 2 == 0) ? "짝수" : "홀수"; 
System.out.println(answer); // 짝수

 

2) swich문

switch(입력변수) {
      case 입력값1: 
               실행 코드
               break;
      case 입력값2: 
               실행 코드
               break;
               ...
      default: 
               실행 코드
                break;
}

 

switch문은 정수형(`int`), 문자형(`char`), 문자열(`String`) 값을 비교하여 해당하는 case 부분을 실행합니다. 단, 대소 비교(>, < 등)는 불가능합니다.

public static int grade(char c) {
    int score = 0;

    switch (c) {

    case 'A':
        score = 100;
        break;
    case 'B':
        score = 80;
        break;
    case 'C':
        score = 60;
        break;
    case 'D':
        score = 40;
        break;
    case 'F':
        score = 0;
        break;
    default:
        score = 0;
        break;

    }
    return score;
}

 

2. 반복문

1) for문

for (초기값  ; 조건식 ; 증감식) { 조건문 }

 

조건이 true이면 계속 반복되고 false가 되면 종료됩니다.

// 1부터 10까지 합 구하기
int sum = 0;
for (int i = 1; i <= 10; i++) { 
    sum += i;
}
System.out.println("총합: " + sum);

 

✅ 초기값 또는 증감식이 생략될 수도 있음 

int n = 2345;
int tot = 0;
for (; n > 0;) { // while문과 비슷한 형태
    tot += n % 10;
    n /= 10;
}
System.out.println("각 자리의 합: " + tot);

 

✅ 향상된 for문

int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
    System.out.println(num);
}

 

2) while문, do-while문

while (조건식) { 조건문 }
do { 조건문 } while (조건식)

 

조건식이 true일때 조건문이 실행됩니다. 조건식이 처음부터 거짓이라면 한 번도 실행되지 않을 수도 있습니다. 따라서 while과 동일하지만 적어도 한 번 실행할 때는 do ~ while을 사용합니다.

 

✅ while문 예제

// 숫자의 각 자리의 합 구하기
int n = 2345;
int tot = 0;

while (n > 0) {
    tot += n % 10;
    n /= 10;
}

System.out.println("각 자리의 합: " + tot);

 

✅ do-while문 예제

int num = 0;
while (num > 0) {
    System.out.println("실행되지 않음");
}

do {
    System.out.println("최소 한 번 실행됨");
} while (num > 0);

 

반복 횟수가 명확할 때나 카운터 변수가 필요할 때는 for문이 유리하고,
반복문 횟수가 정해져 있지 않거나 조건에 따라 언제 종료될지 모를 때는 while문이 유리하다.

 

3. 분기문

1) break문

for문, while문, do-whild 문, switch문을 종료할 때 사용합니다. 중첩된 반복문의 경우 가장 가까운 반복문만 종료하므로 바깥쪽 반복문을 종료시키려면 Label을 사용합니다.

 

✅ 중첩된 반복문 예제

Label: for (...) {
    for(...) {
    	break Label;
    }
}

 

2) continue문

for문,  while문, do-while문에서 사용됩니다. continue문이 실행되면 현재 반복의 나머지 부분은 건너뛰고 for문의 증감식 또는 while문, do-while문의 조건식으로 바로 이동합니다. 반복문을 종료하지 않고 계속 반복을 수행한다는 점에서 break문과 차이가 있습니다.

 

3) return문

메서드의 실행을 종료하고 값을 반환하는 데 사용됩니다. return문은 메서드가 `void`일 경우에는 값 없이 메서드를 종료할 때 사용되고, 값을 반환하는 메서드에서는 반환할 값을 함께 지정해야 합니다.

 

✅ 값 반환 예제

public int sum(int a, int b) {
    return a + b; // 두 값을 더한 결과를 반환
}

 

✅ void 메서드에서의 종료 예제

public void printMessage() {
    System.out.println("메시지 출력");
    return; // 메서드 종료
}
저작자표시 비영리 변경금지 (새창열림)

'☕ Java' 카테고리의 다른 글

[Java Library] QueryDSL  (0) 2024.09.23
[Java] 자바 메서드(Method) 총정리  (0) 2024.09.22
'☕ Java' 카테고리의 다른 글
  • [Java Library] QueryDSL
  • [Java] 자바 메서드(Method) 총정리
파스트잇
파스트잇
  • 파스트잇
    파랑새를 냉장고에 넣는 방법
    파스트잇
    GitHub Ihyeon's GitHub
  • 전체
    오늘
    어제
  • 글쓰기 관리자
    • 전체 글 목록 (14)
      • ☕ Java (5)
        • 🌱 Spring (2)
      • 🟣 C# (0)
      • 🟨 JavaScript (0)
      • 🖥️ Back-End (0)
      • 🌐 Front-End (7)
      • 🧩 Algorithm (1)
        • Coding Test (0)
      • 🚀 Cloud & DevOps (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    html
    스프링부트
    KDT
    java
    반응형
    K-디지털트레이닝
    rc-tree
    반응형 웹
    로그 공간
    css
    Position
    국비개발
    카드형 레이아웃
    자바
    키 페어
    스프링
    보안규칙
    Spring
    국비
    선형 시간
    순수 자바
    상수 공간
    Media Query
    이차 공간
    미디어쿼리
    내용넘칠때
    responsive web
    알고리즘
    메서드
    쿼리dsl
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.0
파스트잇
[Java] 자바 기초 문법
상단으로

티스토리툴바