Java 입출력 스트림 Java I/O는 스트림(stream)을 기반으로 작동합니다. 스트림은 데이터를 순차적으로 처리하는 연속적인 데이터 흐름을 의미하며, Java에서는 java.io 패키지를 통해 다양한 입출력 기능을 제공합니다. 스트림의 분류 바이트 스트림: 바이트 데이터를 처리하는데 사용되며, InputStream과 OutputStream이 기본 클래스입니다. 문자 스트림: 문자 데이터를 처리하는데 사용되며, Reader와 Writer가 기본 클래스입니다. 파일 읽고 쓰기 파일 읽기: FileInputStream 또는 FileReader를 사용하여 파일로부터 데이터를 읽어올 수 있습니다. 파일 쓰기: FileOutputStream 또는 FileWriter를 사용하여 파일에 데이터를 쓸 수 있습니다..
스레드(Thread)란? 스레드는 프로그램 내에서 실제로 작업을 수행하는 실행 단위입니다. 모든 Java 프로그램에는 메인 스레드가 존재하며, 추가적으로 사용자 정의 스레드를 생성하여 병렬 작업을 수행할 수 있습니다. 스레드를 사용하면 여러 작업을 동시에 처리할 수 있어, 애플리케이션의 반응성과 성능을 향상시킬 수 있습니다. 스레드 생성 및 실행 Java에서 스레드를 생성하고 실행하는 방법은 주로 두 가지입니다: Thread 클래스를 상속받는 방법과 Runnable 인터페이스를 구현하는 방법입니다. Thread 클래스 상속 class MyThread extends Thread { public void run() { System.out.println("MyThread is running."); } } My..
람다식(Lambda Expressions) 개념 람다식은 간단히 말해서 익명 함수의 일종입니다. 람다식을 사용하면 메소드를 하나의 식(expression)으로 표현할 수 있으며, 이는 코드를 더 간결하게 만들어 줍니다. 람다식은 주로 함수형 인터페이스(단 하나의 추상 메소드를 가진 인터페이스)와 함께 사용됩니다. 기본 문법 (parameters) -> expression 또는 (parameters) -> { statements; } 예시 // 람다식을 사용하지 않은 경우 new Thread(new Runnable() { @Override public void run() { System.out.println("Thread running"); } }).start(); // 람다식을 사용한 경우 new Thr..
제네릭 프로그래밍의 필요성 제네릭 프로그래밍이 도입되기 전, Java에서는 타입 변환(casting)을 통해 다양한 타입의 객체를 처리했습니다. 하지만 이 방법은 타입 안전성을 보장할 수 없고, 런타임에 ClassCastException과 같은 오류를 발생시킬 위험이 있습니다. 제네릭 프로그래밍은 이러한 문제를 해결해 줍니다. 제네릭의 장점 타입 안전성(Type Safety): 컴파일 시점에 타입 체크를 수행하여 타입 오류를 방지합니다. 코드 재사용성(Reusability): 다양한 타입에 대해 같은 코드를 재사용할 수 있습니다. 캐스팅 제거(Reduction in Casting): 명시적인 타입 변환을 줄여 코드의 가독성을 높입니다. 제네릭의 기본 사용법 제네릭 클래스 정의 public class Bo..
패키지(Package) 정의와 목적 패키지는 관련된 클래스와 인터페이스를 그룹화하여 코드를 조직적으로 관리하는 데 사용됩니다. 이는 네임스페이스 관리, 접근 제어, 코드 재사용성 향상에 도움을 줍니다. 사용 방법 패키지 선언: Java 파일의 맨 위에 package 키워드를 사용하여 패키지를 선언합니다. package com.mycompany.myproject; 패키지 사용: 다른 패키지에 있는 클래스를 사용하려면 import 키워드를 사용하여 해당 클래스를 가져옵니다. import com.mycompany.tools.Tool; 패키지의 장점 네임스페이스 관리: 동일한 이름의 클래스가 다른 패키지에 속할 수 있어 이름 충돌을 방지합니다. 접근 제어: 패키지를 사용하여 클래스의 접근 범위를 제한할 수 있습..
예외 처리란? 예외 처리는 프로그램의 정상적인 흐름을 방해하는 이벤트에 대응하는 코드의 작성을 의미합니다. Java에서는 try, catch, finally, throw, throws 키워드를 사용하여 예외를 처리합니다. 이러한 메커니즘을 통해 개발자는 예외 상황에 대해 명시적으로 대응할 수 있고, 프로그램의 안정성과 신뢰성을 높일 수 있습니다. 예외의 유형 Java에서는 크게 두 가지 유형의 예외를 다룹니다: 체크된 예외(checked exceptions)와 언체크된 예외(unchecked exceptions). 체크된 예외: 컴파일 시간에 체크되는 예외로, 주로 외부의 영향으로 발생하는 예외입니다. 예를 들어, 파일을 읽을 때 해당 파일이 없는 경우 발생합니다. IOException이 이에 해당합니다..
추상 클래스(Abstract Class) 개념 추상 클래스는 하나 이상의 추상 메소드(구현이 없고, 선언만 있는 메소드)를 포함할 수 있는 클래스입니다. 추상 클래스는 직접 인스턴스화할 수 없으며, 상속을 통해 자식 클래스에서 추상 메소드를 구현해야 합니다. abstract class Animal { abstract void makeSound(); void breathe() { System.out.println("I can breathe."); } } 위 예제에서 Animal 클래스는 추상 클래스로, makeSound 메소드는 추상 메소드입니다. breathe 메소드는 일반 메소드로, 구현이 제공됩니다. 사용 이유 공통적인 메소드 구현을 제공하면서도, 일부 메소드는 자식 클래스에서 구현하도록 강제합니다...
상속(Inheritance) 상속은 한 클래스가 다른 클래스의 속성과 메소드를 이어받는 메커니즘입니다. 상속을 통해 기존 코드를 재사용하고 확장할 수 있으며, 이는 코드의 중복을 줄이고 유지보수를 용이하게 합니다. 기본 구조 class Vehicle { public void display() { System.out.println("I am a vehicle."); } } class Car extends Vehicle { @Override public void display() { super.display(); System.out.println("I am a car."); } } Car 클래스는 Vehicle 클래스로부터 상속을 받습니다(extends 키워드 사용). @Override 애노테이션은 Vehi..
클래스(Class) 클래스는 객체를 생성하기 위한 청사진 또는 템플릿입니다. 클래스는 객체의 상태를 나타내는 속성(변수)과 객체의 행동을 나타내는 메소드(함수)로 구성됩니다. 클래스는 데이터와 메소드를 하나의 단위로 묶어 관리할 수 있게 해주는 구조체입니다. public class Car { // Car 클래스의 속성(변수) String brand; int year; // Car 클래스의 메소드 void drive() { System.out.println("This car is driving."); } } 위의 예시에서, Car 클래스는 brand와 year라는 두 개의 속성과 drive라는 메소드를 가지고 있습니다. 이 클래스는 자동차라는 객체를 모델링한 것으로 볼 수 있습니다. 객체(Object) 객..
객체 지향 프로그래밍의 핵심 개념 1. 클래스와 객체 클래스(Class): 객체를 생성하기 위한 템플릿이며, 객체의 상태(속성)와 행동(메소드)을 정의합니다. 객체(Object): 클래스에 의해 생성된 실체로, 클래스의 인스턴스(Instance)라고도 합니다. 각 객체는 독립된 상태와 행동을 가집니다. public class Car { // 속성 String brand; int year; // 메소드 public void drive() { System.out.println("The car is driving."); } } 2. 캡슐화(Encapsulation) 캡슐화는 객체의 상태를 보호하고, 외부에서의 무분별한 접근을 제한하는 기법입니다. 주로 private 키워드를 사용하여 데이터를 숨기고, publ..
Java 배열 배열은 동일한 타입의 여러 변수를 하나의 묶음으로 관리할 수 있는 데이터 구조입니다. 배열을 사용하면 인덱스를 통해 각 요소에 접근할 수 있으며, 배열의 크기는 생성 시에 정해지고 변경할 수 없습니다. 배열의 선언과 초기화 int[] numbers = {1, 2, 3, 4, 5}; // 배열 선언과 동시에 초기화 String[] names = new String[5]; // 크기가 5인 String 배열 생성 names[0] = "John"; // 배열의 첫 번째 요소에 값 할당 배열은 반복문과 함께 사용되어 데이터 집합을 효과적으로 처리할 수 있습니다. for (int i = 0; i < numbers.length; i++) { System.out.println(numbers[i]); /..
조건문 조건문은 주어진 조건에 따라 프로그램의 실행 흐름을 분기합니다. Java에서는 if-else 문과 switch 문 두 가지 형태의 조건문을 제공합니다. if-else 문 if-else 문은 가장 기본적인 조건 분기문입니다. 조건이 true일 때 특정 코드 블록을 실행합니다. int score = 75; if (score >= 90) { System.out.println("A grade"); } else if (score >= 80) { System.out.println("B grade"); } else if (score >= 70) { System.out.println("C grade"); } else { System.out.println("D grade"); } switch 문 switch 문은..