728x90
반응형

1. Servlet

1. Network 통신

1. Server-client Model

  • 서버는 특정 서비스를 제공하는 컴퓨터를 말하며, 클라이언트는 해당 서비스를 이용하는 사용자를 의미한다.

Servlet 사진 1

 

2. Servlet의 종류

  1. Web Server : 웹 브라우저와 HTTP 프로토콜을 사용하여 사용자의 요구에 따른 특정 서비스를 제공하는 서버
  2. Mail Server : 인터넷을 통해 사용자 간의 전자 우편을 주고 받는 서비스 제공
  3. FTP Server : 서버 내에 파일을 업로드, 다운로드 할 수 있도록 파일 관리 기능 제공
  4. Telnet Server : Terminal, 텍스트로만 이루어진 창에서 특정 명령어를 통해 원격지 서버를 접속 및 관리
  5. Database Server : 데이터를 저장하고, 원격지에 접속할 경우 권한에 따라 해당 데이터를 열람, 추가, 수정, 삭제하는 기능 처리

 

2. Web 통신

1. Web 통신 구조

servlet 사진 2

 

2. Web Server 란

  • 사용자에게 HTML 페이지나 jpg, png와 같은 이미지를 HTTP 프로토콜을 통해 웹 브라우저에 제공하는 서버로, 내부의 내용이 이미 만들어져 있는 정적인 요소들을 화면에 보여주는 역할을 한다.

3. 개별(로컬)프로그램과 서버 프로그램의 특징

  • 개별 프로그램의 특징 및 단점

servlet 사진 3

  1. 프로그램 업데이트 발생 시 각각 다시 다운로드 해야 한다.
  2. 각 프로그램에서 생성된 데이터 개별 저장되므로 공유 불가하다.

  • 서버 프로그램 특징

servlet 사진 4

  1. 프로그램 업데이트 발생 시 서버가 상관하지 않아도 클라이언트가 서버에서 다운 받아 업데이트를 개별적으로 진행한다.
  2. 데이터는 서버에 일괄 저장된다.

3. Web Server의 종류

servlet 사진 5

  • Apache Software Foundation에서 만든 서버로 HTTP 통신에 대한 여러 라이브러리를 제공한다.

 

servlet 사진 6

  • Window OS에서 제공하는 웹 서버로, 높은 수준의 보안성과 성능을 제공한다.

 

servlet 사진 7

  • 무료 오픈 소스 서버로, 사용자 요청을 스레드가 아닌 확장성이 있는 이벤트 기반 설계를 통해 필요 리소스만 할당하여 사용한다.

 

4. WAS란

  • Web Application Server의 약자로, 사용자가 요청한 서비스의 결과를 스크립트 언어 등으로 가공하여 생성한 동적인 페이지를 사용자에게 보여주는 역할을 한다.
  • Web Application이란
    • 정적인 페이지를 제공하는 미리 완성된 클라이언트 프로그램이다.
    • 브라우저만 설치되어 있으면 서버에 요청해 언제든 볼 수 있다.
    • 클라이언트 요청(= url 요청)에 따라 서버가 응답을 html 태그 문법인 텍스트로 전송하면, 브라우저가 해당 텍스트를 해석해 띄워주는 방식이다.
    • 서버는 클라이언트 요청(request)에 반드시 응답(response)해야 한다.
      • 응답할 내용이 없으면, 응답 내용이 없다는 응답이라도 해야 한다.

 

5. WAS의 종류

servlet 사진 8

  • Apache Software Foundation에서 서블릿과 JSP를 통한 동적인 웹 문서를 처리하기 위해 만든 웹 애플리케이션 서버이다.

 

servlet 사진 9

  • Jboss라고도 불리며, tomcat이 제공하는 servlet container뿐만 아니라 EJB container를 별도로 제공하여 폭넓은 서비스를 구현한다.

 

servlet 사진 10

  • 국산 WAS로, 대용량 데이터 트랜잭션을 고성능으로 처리하며 개발 및 운영에 관한 기술 지원이 뛰어나다.

 

6. Web & WAS

servlet 사진 11

  • 구조: Web browser ↔ Web (html) ↔ WAS
  • web(html)은 사전에 작성된 화면으로 정적인 페이지(사전에 작성된 화면)를 의미한다. 서버는 따로 두고 일단 클라이언트 요청에 대해 web에서 응답한 뒤에, 처리할 동적 요청 등 필요에 따라 was에 요청하여 응답한다.
  • WAS는 Servlet을 보관하다가 서블릿 라이프사이클에 따라 생성, 소멸 등을 주관하는 역할을 하여, 다른 말로 Servlet Container라고도 부른다.

 

3. CGI & WAS

1. CGI

  • CGI(Common Gateway Interface)는 웹 서버가 직접적으로 웹 프로그램을 실행하는 것을 말한다.
  • 동일 프로그램에 대한 요청이 있을 때마다 각각의 프로그램을 실행하여, 요청과 프로그램이 1:1 매칭되어 실행된다.

servlet 사진 12

  • Perl이나 C/C++ 언어를 사용하여 웹 서버가 실행할 수 있는 프로그램을 작성한다.

 

2. WAS

  • WAS(Web Application Server)는 웹 서버가 웹 애플리케이션 서버에 요청하면, 웹 애플리케이션 서버가 해당 프로그램을 실행하는 방식이다.
  • 동일 프로그램에 여러 요청이 있으면 한 개의 프로그램을 실행하여 다수 요청을 처리한다.

servlet 사진 13

 

3. Container (Servlet, JSP)

  • Servlet-Container
    • Servlet의 생명 주기(생성,초기화,소멸)를 관리한다.
    • HttpServletRequest, HttpServletResponse 객체를 생성한다.
    • 요청에 따라 멀티스레딩 구성이 가능하며, 전송 방식에 따라 동적으로 페이지 구성하는 작업을 진행한다.
    • 정적 로딩 처리를 한다.
  • JSP-Container
    • JSP 파일을 java코드로 변경해주고 class파일로 전환하여 메모리 공간에 로드한 뒤 실행 가능하게 만드는 작업(= Servlet화)을 한다.
    • 처리 결과를 HTML파일로 만들어주는 작업을 진행한다.
    • 동적 로딩 처리를 한다.

 

4. Web Server & WAS

구분 장점 단점
Web Server - 빠른 처리 속도  → 요청에 대한 결과 페이지만 전송
- 쉬운 구현  → HTML같은 단순한 문서만으로 구성
- 한정적인 서비스  → 만들어진 정보만 보여주므로 서비스가 한정적임
- 글의 추가, 수정, 삭제가 어려움  → 문서의 내용이 변경될 경우 직접 수정
WAS - 서비스의 다양성  → 여러 데이터 활용 가능
- 글의 추가, 수정, 삭제가 쉬움  → 문서 내용이 변경되면 직접 수정하지 않음
- 느린 처리 속도  → 데이터를 처리하여 결과 전송
- 어려운 구현  → 서비스에 해당하는 소스 직접 작성

 

728x90
반응형
728x90
반응형

1. DriverManager

1. DriverManager Class

  • 데이터 원본(= Database)에 JDBC driver를 통하여 Connection을 만드는 역할을 한다.
  • Driver란 중간에서 연결하는 역할을 의미한다.
  • Class.forName() method를 통해 생성되어 메모리에 할당된다.
    • Class.forName()에서 Class 클래스는 클래스의 메타 정보 가지고 있다.
    • forName() 메소드에 풀클래스명을 작성하면 해당 클래스를 메모리에 올려 사용할 준비를 하도록 하는 것으로, 동적 로딩을 이용하여 DB driver를 로딩한다.

2. DriverManager Class 사용 시 주의 사항

  • 반드시 예외 처리를 해야 한다.
  • 직접 instance 생성이 불가하고, DriverManager 클래스의 getConnection() 메소드를 사용하여 Connection instance를 생성할 수 있다.

3. DriverManager Class 활용 예시

  1. Class.forName() 메소드를 활용해 사용할 Driver를 등록한다.
    • 아래 코드는 MySQL JDBC Driver 클래스를 등록한다.
    • ClassNotFoundException에 대한 예외 처리를 반드시 해야 한다.
    Class.forName("com.mysql.cj.jdbc.Driver");
  2. DriverManager를 이용해 Connection 객체를 생성할 수 있다.
    • getConnection() 메소드의 매개변수 속성은 다음과 같다.
      • url : 연결할 Database의 주소
      • user : Database에 접속할 user 이름
      • password : Database 접속을 위한 비밀번호
    Connection con  = null;
    try { 
    	con = DriverManager.getConnection("jdbc:mysql://localhost/DB이름", user, password);
    }
  3. Properties 파일을 활용하여 수기로 작성하지 않고 속성 값을 불러와 코드를 작성할 수 있다.
    • 수기로 매번 설정 속성을 작성할 경우 다음과 같은 문제점이 있으므로 설정 속성 파일을 분리하여 사용하는 것이 일반적이다.
      1. 수기로 작성하면서 오타가 발생할 가능성이 높아진다.
      2. 설정 속성에 수정 사항이 발생할 경우 파일마다 번거롭게 수정해야 하므로, 유지보수 비용이 증가한다.
      3. Connection을 사용하는 파일마다 동일한 코드를 중복 작성하게 된다.
    • JDBD Configuration Properties 파일 작성
      • driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost/DB이름 user=user password=password
    • Properties 파일을 읽어와 Connection 객체를 생성하는 코드 작성
      • properties 파일에 key-value 방식으로 저장한 설정 정보를 읽어온다.
      • 인자로 url, user, password를 줘도 되고, url, prop를 줘도 된다. (user와 password를 분리하지 않고 보낼 수 있다.)
        Properties prop = new Properties();
        Connection con = null;
        
        try {
            prop.load(new FileReader("jdbc-config.properties"));
        
            String driver = prop.getProperty("driver");
            String url = prop.getProperty("url");
            String user = prop.getProperty("user");
            String password = prop.getProperty("password");
        
            Class.forName(driver);
            con = DriverManager.getConnection(url, user, password);
        }
        

2. Connection

1. Connection Class

  • 특정 데이터 원본(= Database)과 연결된 Connection을 나타낸다.
  • 쿼리문을 실행할 수 있는 Statement 혹은 PreparedStatement 객체를 생성할 수 있는 기능을 제공한다.
    • Connection instance를 생성하고 createStatement() 메소드를 호출하여 Statement instance를 생성할 수 있다.
    • 따라서 SQL문 실행 전 우선 Connection instance가 있어야 한다.

2. Connection Class 활용

  • Connection 객체 생성 시 생성 전에 설정한 데이터베이스 주소로 ping을 보내 연결이 정상일 경우에 객체를 생성한다.
  • Connection 객체 자원은 사용 후 반드시 반납해야 한다.
  • Connection 객체를 생성하는 코드 예시는 위에서 DriverManager 클래스를 활용하여 확인하였으므로 생략한다.
  • Connection 객체를 생성하는 코드 또한 중복 작성하게 되므로, Template 클래스의 static 메소드로 Connection 객체를 생성하거나 반납하는 코드를 작성하여 공통으로 사용하도록 하는 것이 일반적이다.
    • 자원 반납 시에는 null 체크와 이미 반납된 자원이 아닌지 확인해야 한다.
    • Template 코드 작성 예시
    •  
public class JDBCTemplate {

    public static Connection getConnection() {
        Connection con = null;
				//DriverManager를 활용한 Connnection 객체 생성 코드 생략
        return con;
    }

	public static void close(Connection con) {
        try {
            if(con != null & !con.isClosed()) {
                con.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
}

3. Statement

1. Statement Class 특징

  • SQL문을 저장하고 실행한 뒤 결과를 받아 반환해주는 메소드들이 묶여 있는 타입의 클래스이다.
  • 생성한 instance의 executeQuery() 메소드를 호출하여 SQL문 수행한다. (SQL문을 String 형태로 인자로 전달한다.)

2. Statement 객체 생성 및 사용

  1. Connection class의 createStatement() 메소드를 호출하여 Statement instance를 생성한다.
  • 사용 예시
try {
	String query = "SELECT ID, LAST_NAME FROM EMP";
	stmt = conn.createStatement(); // conn = Connection 객체이다.
	rset = stmt.executeQuery(query);
} catch (SQLException e) {
	e.printStackTrace();
}

4. PreparedStatement

1. PreparedStatement Class 특징

  • PreparedStatement도 Statement이다. 따라서 Template 클래스를 작성하여 Statement를 close() 하는 메소드를 함께 사용할 수 있다.
  • 완성된 쿼리문과 미완성된 쿼리문(= 위치홀더를 사용한 쿼리문)을 모두 사용할 수 있다.
  • PreparedStatement는 위치홀더(placeholder) 개념에 해당되는 인수가 많아 특정 값만 바꾸어 여러 번 실행하는 상황에 유용하다.

2. PreparedStatement 장점

  • 수행 속도가 빠르다.
    • Java 쿼리문은 파싱을 통해 유효성 검사, 연산식 등의 유효성 검사를 거친 뒤에 컴파일되어 Database에서 쿼리를 수행해 결과 값을 가지고 오는 구조이다.
    • Statement는 SQL문 실행 시 쿼리문을 전달하므로, 매번 새로운 쿼리로 인식하기 때문에 조건값에 따라 컴파일을 새로 해야 한다.
    • 하지만 PreparedStatement는 조건값을 ?로 두고 쿼리를 준비시킨 뒤, 쿼리는 변경하지 않고 변경되지 않으므로 바인딩 되는 변수만 바꿔 조회한다. 따라서 한번 컴파일한 뒤 캐시에 담아두고 수행한다.

⇒ PreparedStatement가 Statement보다 수행 속도가 빠르다.

  • SQL injection 공격에 대하여 안전하다.
    • Statement 사용 시 전달하는 조건 변수에 OR 1=1 조건을 작성하면 시스템이 제공하는 의도와 다르게 데이터가 조회될 수 있다.
    • 예를 들어 아래처럼 조건을 주게 되면, empName이 홍길동인 사람이 아니라 empID가 200인 사람의 정보를 조회하게 된다.
    • 하지만 PreparedStatement와 위치홀더를 사용하면, 조건으로 세팅되는 값을 메소드의 지정 형식에 따라 따옴표로 감싸는 등의 처리를 알아서 한다.
    • OR 1=1 조건이 악의적인 의도대로 사용되지 못하므로 Sql Injection 공격에 안전하다.
    • 대부분의 경우PreparedStatement가 빠르고 안전하므로, 특수 케이스가 아니면 PreparedStatement 사용을 권장한다.
SQL Injection이란
악의적으로 SQL문을 실행되게 하여 Database를 비정상적으로 조작하는 코드 주입 공격이다.특히 관리자 계정으로 접근해 사용자 정보를 해킹하는 사례가 있었다.매우 초보적인 방법이라 유용한 해킹 기법 아니며, 현재는 거의 모든 사이트에서 방어하고 있다. 

3. PreparedStatement 객체 생성 및 사용

  • Connection class의 preparedStatement() 메소드를 사용하여 instance 생성한다.
  • SQL문을 위치홀더(placeholder) 「?」로 표현하는 String으로 정의한다.
  • PreparedStatement의 setString() 메소드로 위치홀더의 순서와 넣어 줄 변수 값을 세팅한다.
  • 생성하고 위치홀더 값을 세팅한 instance의 executeQuery() 메소드를 호출하여 SQL문 수행한다.
try {
	String query = "INSERT INTO MEMBER VALUES(?, ?)";
	pstmt = conn.preparedStatement(query);
	pstmt.setString(1, id);
	pstmt.setString(2, password);
	rset = pstmt.executeQuery();
} catch (SQLException e) {
	e.printStackTrace();
}

4. SQL문 관리

  • SQL문을 XMl파일로 분리하여 관리할 수 있다.
  • 쿼리 XML 파일 작성 예시
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment/>
    <entry key="selectEmpByFamilyName">
        SELECT
        E.*
        FROM EMPLOYEE E
        WHERE E.EMP_NAME LIKE CONCAT(?, '%')
    </entry>
</properties>
  • XML 파일의 쿼리를 읽어와 사용하는 코드 작성 예시
try {
    prop.loadFromXML(new FileInputStream("query.xml"));
    String query = prop.getProperty("selectEmpByFamilyName");

    pstmt = con.prepareStatement(query);
    pstmt.setString(1, empName);

    rset = pstmt.executeQuery();
}

5. ResultSet

1. ResultSet Class

  • SELECT문 수행 성공 시 반환한 결과값을 받아오는 객체이다.
  • SQL문에 의해 생성된 결과 테이블을 담고 있다.
  • 커서(cursor)로 특정 행에 대한 참조 조작을 할 수 있다.
  • Connection과 Statement도 close()로 자원 반납하듯, ResultSet도 close()를 통해 자원을 반납해야 한다.

2. ResultSet method

  • getString()
    • ResultSet의 현재 커서 위치에 존재하는 로우에서 인자로 전달한 컬럼의 결과 값을 가지고 온다.
    • 데이터 자료형에 따라 get자료형(”컬럼명”) 형식으로 사용한다.
  • next()
    • ResultSet의 커서 위치를 하나 내리면서 다음 행이 존재하면 true 존재하지 않으면 false를 반환한다.
    • while문을 활용하여 쿼리 수행 결과의 마지막 행까지 반복 수행하여 결과를 한 행씩 가지고 올 때 활용한다.
    • 단, 수행 결과 반환될 컬럼이 1건임이 확실하면 while 블럭 대신 if문에 조건으로 사용할 수 있다.
  • 적용 코드 예시
while(rset.next()) {
    System.out.println(rset.getString("EMP_ID") + ", " + rset.getString("EMP_NAME"));
}
728x90
반응형

'이것 저것 개발 공부 > MySQL' 카테고리의 다른 글

[JDBC] JDBC와 MVC 패턴의 핵심 개념 정리 및 실습 코드 예제  (1) 2025.03.05
[JDBC] JDBC  (0) 2025.03.05
[MySQL] DATE TYPES, VIEW  (0) 2025.03.03
[MySQL] SET, CONSTRAINT  (0) 2025.03.03
[MySQL] JOIN, SUBQUERIES  (0) 2025.03.03
728x90
반응형

[Java] Java Enum이란? 열거형 타입 개념과 활용법 총정리

 

[Java] Enum Type

1. Enum 개요1. Enum 이란Enum (Enumeration Type, 열거형)은 상수 값들의 집합을 정의하는 특별한 데이터 타입입니다.일반적인 final static 상수보다 가독성이 높고 유지보수가 쉬운 장점이 있습니다.2. En

crushed-taro.tistory.com

1. 람다 개요

1. 람다식(Lambda Expression)이란

람다식은 익명 함수(Anonymous Function)를 단순한 표현식으로 나타내는 방식으로, Java 8부터 지원됩니다.

2. 람다식이 등장한 이유

기존에는 익명 클래스를 활용해 함수를 정의해야 했지만, 코드가 길고 가독성이 떨어졌습니다.

람다식을 사용하면 코드를 더 간결하게 작성할 수 있고, 함수형 프로그래밍 패러다임을 적용할 수 있습니다.

3. 람다식 기본 문법

  • 코드가 간결해지고 가독성이 향상됩니다.
  • 익명 함수처럼 활용 가능하며, 필요할 때 즉시 정의하여 사용할 수 있습니다.
// (매개변수) -> { 실행할 코드 }

// 기존 익명 클래스 방식
Comparator<Integer> comparator = new Comparator<Integer>() {
    @Override
    public int compare(Integer a, Integer b) {
        return a - b;
    }
};

// 람다식 적용
Comparator<Integer> comparatorLambda = (a, b) -> a - b;

2. 함수적 인터페이스 (@FunctionalInterface)

1. 함수적 인터페이스란

함수형 인터페이스(Functional Interface)는 단 하나의 추상 메서드만 가지는 인터페이스입니다.

람다식을 사용하려면 함수형 인터페이스가 필수적입니다.

2. @FunctionalInterface 어노테이션

Java에서는 함수형 인터페이스를 정의할 때 @FunctionalInterface를 사용하여 컴파일러가 올바르게 작성되었는지 검증할 수 있습니다.

@FunctionalInterface
interface MyFunction {
    int apply(int a, int b);
}

1. 기본 제공 함수형 인터페이스 (java.util.function 패키지)

  • Predicate<T> → boolean test(T t) (조건 검사)
  • Function<T, R> → R apply(T t) (입력값을 변환)
  • Consumer<T> → void accept(T t) (입력값 소비)
  • Supplier<T> → T get() (값 제공)
Function<String, Integer> lengthFunction = str -> str.length();
System.out.println(lengthFunction.apply("Lambda")); // 6

3. 메서드 참조

람다식이 더욱 간결해질 수 있도록 메소드 참조(Method Reference)를 활용할 수 있습니다.

1. 메서드 참조 기본 문법

클래스명::메서드명
객체참조::메서드명

2. 정적 메서드 참조

Function<Integer, String> intToString = String::valueOf;
System.out.println(intToString.apply(100)); // "100"

3. 인스턴스 메서드 참조

String str = "hello";
Supplier<Integer> lengthSupplier = str::length;
System.out.println(lengthSupplier.get()); // 5

4. 생성자 참조

Supplier<List<String>> listSupplier = ArrayList::new;
List<String> list = listSupplier.get();

4. 람다식을 활용한 스트림(Stream) 처리

Java에서는 람다식을 활용하여 Stream API와 함께 데이터를 손쉽게 처리할 수 있습니다.

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 람다식 활용
List<String> filteredNames = names.stream()
                                  .filter(name -> name.startsWith("A"))
                                  .collect(Collectors.toList());

System.out.println(filteredNames); // ["Alice"]

5. 람다식과 병렬 처리 (Parallel Stream)

람다식은 멀티코어 환경에서도 효율적으로 병렬 처리를 할 수 있도록 도와줍니다.

parallelStream()을 활용하면 데이터를 병렬로 처리하여 성능을 향상시킬 수 있습니다.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 병렬 스트림 활용
int sum = numbers.parallelStream()
                 .reduce(0, Integer::sum);

System.out.println(sum); // 55
728x90
반응형

'이것 저것 개발 공부 > JAVA' 카테고리의 다른 글

[Java] Java Enum이란? 열거형 타입 개념과 활용법 총정리  (1) 2025.03.01
[Java] 입출력  (0) 2025.03.01
[Java] 예외처리  (0) 2025.03.01
[Java] 제네릭스와 컬렉션  (1) 2025.02.28
[Java] 다형성  (1) 2025.02.28
728x90
반응형

 

1. Enum 개요

1. Enum 이란

Enum (Enumeration Type, 열거형)은 상수 값들의 집합을 정의하는 특별한 데이터 타입입니다.

일반적인 final static 상수보다 가독성이 높고 유지보수가 쉬운 장점이 있습니다.

2. Enum 기본 문법

Enum을 정의할 때는 enum 키워드를 사용합니다.

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

3. Enum을 사용하는 이유

  • 가독성 향상: 의미 있는 이름을 부여하여 코드 가독성을 높임
  • 타입 안정성: 잘못된 값을 방지 (문자열, 정수 상수보다 안전)
  • 객체처럼 활용 가능: 메서드, 생성자 포함 가능

2. Enum 활용

1. Enum 값 사용하기

public class EnumExample {
    public static void main(String[] args) {
        Day today = Day.MONDAY;
        System.out.println("오늘은 " + today + "입니다.");
    }
}

2. Enum의 값 반복 처리

for (Day day : Day.values()) {
    System.out.println(day);
}

3. Enum에 필드 & 생성자 추가하기

Enum에 필드와 생성자를 추가하여 더 강력하게 활용할 수 있습니다.

public enum Status {
    SUCCESS(200), ERROR(500), NOT_FOUND(404);

    private final int code;

    Status(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }
}

1. 활용 예제

public class EnumTest {
    public static void main(String[] args) {
        Status status = Status.SUCCESS;
        System.out.println("상태 코드: " + status.getCode());
    }
}

// 상태 코드: 200

4. Enum에서 메서드 활용하기

Enum에 추상 메서드를 정의하여 각 열거형 값마다 다른 동작을 수행할 수 있습니다.

public enum Operation {
    ADD {
        public int apply(int x, int y) {
            return x + y;
        }
    },
    SUBTRACT {
        public int apply(int x, int y) {
            return x - y;
        }
    };

    public abstract int apply(int x, int y);
}

1. 활용 예제

public class EnumMethodExample {
    public static void main(String[] args) {
        System.out.println(Operation.ADD.apply(5, 3)); // 8
        System.out.println(Operation.SUBTRACT.apply(5, 3)); // 2
    }
}

5. Enum을 활용한 실전 예제 (Switch문 & 데이터 매핑)

1. Enum과 Switch문

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

        switch (today) {
            case MONDAY:
                System.out.println("월요일입니다.");
                break;
            case FRIDAY:
                System.out.println("금요일입니다.");
                break;
            default:
                System.out.println("오늘은 " + today + "입니다.");
        }
    }
}
728x90
반응형

'이것 저것 개발 공부 > JAVA' 카테고리의 다른 글

[Java] Java 람다식(Lambda Expression) 제대로 이해하기  (1) 2025.03.01
[Java] 입출력  (0) 2025.03.01
[Java] 예외처리  (0) 2025.03.01
[Java] 제네릭스와 컬렉션  (1) 2025.02.28
[Java] 다형성  (1) 2025.02.28
728x90
반응형

1. 입출력 개요

1. Java 입출력이란

입출력(I/O, Input and Output)이란 프로그램이 외부에서 데이터를 입력받고 출력하는 과정을 의미합니다.

Java에서는 java.io 패키지와 java.nio 패키지를 사용하여 입출력을 처리할 수 있습니다.

2. 입출력 방식의 종류

Java의 입출력은 크게 기본 스트림 (Stream)과 NIO (New I/O) 방식으로 나뉩니다.

 Stream (기본 I/O): InputStream, OutputStream, Reader, Writer 사용

 NIO (New I/O): java.nio 패키지를 활용하여 버퍼(Buffer) 기반의 비동기 처리 지원

2. 파일 관련 입출력

1. 파일 입력 (File Input)

Java에서 파일을 읽을 때 FileReader, BufferedReader, FileInputStream 등을 사용할 수 있습니다.

import java.io.*;

public class FileReadExample {
    public static void main(String[] args) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader("example.txt"));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            reader.close();
        } catch (IOException e) {
            System.out.println("파일을 읽는 중 오류 발생: " + e.getMessage());
        }
    }
}

2. 파일 출력 (File Output)

파일에 데이터를 쓰려면 FileWriter, BufferedWriter, FileOutputStream 등을 사용할 수 있습니다.

import java.io.*;

public class FileWriteExample {
    public static void main(String[] args) {
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"));
            writer.write("Java 파일 입출력 예제입니다.");
            writer.newLine();
            writer.close();
        } catch (IOException e) {
            System.out.println("파일을 쓰는 중 오류 발생: " + e.getMessage());
        }
    }
}

3. 바이트 기반 vs 문자 기반 스트림

Java의 입출력 스트림은 바이트 기반 문자 기반으로 구분됩니다.

스트림 종류 클래스 설명
바이트 기반 입력 InputStream 바이트 단위 데이터 입력
바이트 기반 출력 OutputStream 바이트 단위 데이터 출력
문자 기반 입력 Reader 문자 단위 데이터 입력
문자 기반 출력 Writer 문자 단위 데이터 출력

1. 바이트 스트림 예제 (InputStream & OutputStream)

import java.io.*;

public class ByteStreamExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("image.jpg");
             FileOutputStream fos = new FileOutputStream("copy.jpg")) {
            
            int data;
            while ((data = fis.read()) != -1) {
                fos.write(data);
            }
        } catch (IOException e) {
            System.out.println("파일 입출력 오류 발생: " + e.getMessage());
        }
    }
}

2. 문자 스트림 예제 (Reader & Writer)

import java.io.*;

public class CharStreamExample {
    public static void main(String[] args) {
        try (FileReader reader = new FileReader("text.txt");
             FileWriter writer = new FileWriter("copy.txt")) {
            
            int data;
            while ((data = reader.read()) != -1) {
                writer.write(data);
            }
        } catch (IOException e) {
            System.out.println("파일 입출력 오류 발생: " + e.getMessage());
        }
    }
}

4. 버퍼링 (Buffering)과 성능 최적화

1. 버퍼링이란

파일을 읽고 쓸 때 버퍼(Buffer)를 사용하면 속도가 빨라집니다.

 BufferedReader / BufferedWriter → 텍스트 처리 속도 향상

 BufferedInputStream / BufferedOutputStream → 바이너리 처리 속도 향상

import java.io.*;

public class BufferedExample {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("largeFile.txt"));
             BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
            
            String line;
            while ((line = br.readLine()) != null) {
                bw.write(line);
                bw.newLine();
            }
        } catch (IOException e) {
            System.out.println("버퍼링 입출력 오류 발생: " + e.getMessage());
        }
    }
}

5. 자주 발생하는 입출력 예외 처리

예외 유형   원인 해결 방법
FileNotFoundException 파일이 존재하지 않음 파일 경로 확인
IOException 읽기/쓰기 중 오류 try-catch 블록으로 예외 처리
SecurityException 접근 권한 없음 파일 권한 확인

 

728x90
반응형
728x90
반응형

1. 예외처리 개요

1. 예외(Exception)란

Java에서 예외(Exception)는 프로그램 실행 중 발생하는 오류를 의미합니다.

예외가 발생하면 프로그램이 갑자기 종료될 수 있으므로, 이를 적절히 처리하는 것이 중요합니다.

2. 예외처리가 필요한 이유

 프로그램이 갑자기 종료되는 것을 방지

 오류 원인을 명확하게 파악하고 해결 가능

 안전한 코드 작성 (예: 파일 읽기/쓰기 실패 시 대비)

 

예외 처리는 try-catch 문, throws 키워드, finally 블록 등을 사용하여 구현할 수 있습니다.

2. 예외 클래스의 종류

Java에서 예외는 크게 Checked Exception Unchecked Exception으로 나뉩니다

1. Checked Exception (컴파일러 체크 예외)

 프로그램 실행 전에 컴파일러가 예외 발생 가능성을 체크

 반드시 예외를 처리해야 함 (try-catch 또는 throws 사용)

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class CheckedExceptionExample {
    public static void main(String[] args) {
        try {
            File file = new File("test.txt");
            FileReader fr = new FileReader(file);
        } catch (IOException e) {
            System.out.println("파일을 찾을 수 없습니다: " + e.getMessage());
        }
    }
}

2. Unchecked Exception (실행 시점 예외)

 컴파일 시점이 아니라 실행 중 발생

 예외 처리가 강제되지 않음

public class UncheckedExceptionExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3};
        System.out.println(numbers[5]); // ArrayIndexOutOfBoundsException 발생
    }
}

3. Error 클래스

 시스템 레벨에서 발생하는 심각한 오류

 예: OutOfMemoryError, StackOverflowError

3. 예외 처리 방법

1. try-catch 문

예외가 발생할 가능성이 있는 코드를 try 블록에 작성하고, 예외가 발생하면 catch 블록에서 처리합니다.

public class TryCatchExample {
    public static void main(String[] args) {
        try {
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("0으로 나눌 수 없습니다!");
        }
    }
}

2. throws 키워드

메서드에서 예외를 직접 처리하지 않고 호출한 곳에서 처리하도록 위임합니다.

public class ThrowsExample {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(1000); // Checked Exception (InterruptedException)
    }
}

3. finally 블록

예외 발생 여부와 관계없이 항상 실행되는 코드를 작성할 때 사용합니다.

public class FinallyExample {
    public static void main(String[] args) {
        try {
            int result = 10 / 2;
            System.out.println("결과: " + result);
        } catch (ArithmeticException e) {
            System.out.println("예외 발생");
        } finally {
            System.out.println("이 코드는 항상 실행됩니다.");
        }
    }
}

4. 사용자 정의 예외 (Custom Exception)

필요에 따라 직접 예외 클래스를 정의할 수도 있습니다.

class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}

public class CustomExceptionExample {
    public static void main(String[] args) {
        try {
            throw new MyException("사용자 정의 예외 발생!");
        } catch (MyException e) {
            System.out.println(e.getMessage());
        }
    }
}
728x90
반응형

'이것 저것 개발 공부 > JAVA' 카테고리의 다른 글

[Java] Java Enum이란? 열거형 타입 개념과 활용법 총정리  (1) 2025.03.01
[Java] 입출력  (0) 2025.03.01
[Java] 제네릭스와 컬렉션  (1) 2025.02.28
[Java] 다형성  (1) 2025.02.28
[Java] 상속  (0) 2025.02.28
728x90
반응형

1. 제네릭스(Generic)란

제네릭스(Generic)는 자바에서 컴파일 시 타입을 체크할 수 있도록 하는 기능입니다. 이를 통해 타입 안정성을 보장하고, 불필요한 형 변환(casting)을 줄일 수 있습니다.

// 제네릭스를 사용한 클래스 예제
class Box<T> {
    private T item;
    
    public void setItem(T item) {
        this.item = item;
    }
    
    public T getItem() {
        return item;
    }
}

public class GenericExample {
    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.setItem("Hello Generics");
        System.out.println(stringBox.getItem());
    }
}

1 제네릭스의 장점

  • 컴파일 타임 타입 체크 → 타입 안정성 보장
  • 형 변환 필요 없음 → 코드 간결화
  • 재사용성 증가 → 다양한 타입을 지원

2. 와일드카드 (Wildcards)

1. 종류

  • <?> : 모든 타입 허용 (Unbounded Wildcard)
  • <? extends T> : T 또는 T의 하위 클래스만 허용 (Upper Bounded)
  • <? super T> : T 또는 T의 상위 클래스만 허용 (Lower Bounded)
public static void printList(List<?> list) {
    for (Object obj : list) {
        System.out.println(obj);
    }
}

3. 컬렉션 프레임워크

컬렉션(Collection)은 데이터를 효율적으로 저장하고 관리하기 위한 자바의 자료구조입니다.

1 주요 컬렉션 인터페이스

  • List → 순서가 있는 자료구조, 중복 허용 (ArrayList, LinkedList 등)
  • Set → 중복을 허용하지 않는 자료구조 (HashSet, TreeSet 등)
  • Map → 키-값 쌍을 저장하는 자료구조 (HashMap, TreeMap 등)

4. List 인터페이스

1. List 특징

  • 순서가 있는 데이터 저장
  • 중복 데이터 허용
  • 배열과 비슷하지만 크기 동적 변경 가능
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("JavaScript");

System.out.println(list.get(0)); // Java

5. Set 인터페이스

1. Set 특징

  • 중복을 허용하지 않음
  • 순서가 보장되지 않음 (일부 구현체 제외)
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Python");
set.add("Java"); // 중복 추가되지 않음

System.out.println(set.size()); // 2

6. Map 인터페이스

1. Map 특징

  • 키(Key)-값(Value) 쌍으로 데이터 저장
  • 키는 중복 불가능, 값은 중복 가능
Map<Integer, String> map = new HashMap<>();
map.put(1, "Java");
map.put(2, "Python");
map.put(1, "C++"); // 키가 같으면 값이 덮어쓰기됨

System.out.println(map.get(1)); // C++

 

728x90
반응형

'이것 저것 개발 공부 > JAVA' 카테고리의 다른 글

[Java] 입출력  (0) 2025.03.01
[Java] 예외처리  (0) 2025.03.01
[Java] 다형성  (1) 2025.02.28
[Java] 상속  (0) 2025.02.28
[Java] 객체 배열  (0) 2025.02.27
728x90
반응형

1. 다형성(Polymorphism)이란

다형성(Polymorphism)은 객체 지향 프로그래밍(OOP)의 핵심 개념 중 하나로, 동일한 인터페이스를 가진 객체들이 다양한 방식으로 동작할 수 있도록 하는 기능입니다. 즉, 같은 메서드를 호출해도 객체에 따라 다른 결과가 나올 수 있습니다.

1. 다형성의 주요 특징

  • 업캐스팅(Upcasting): 자식 클래스의 객체를 부모 클래스 타입으로 변환
  • 오버로딩(Overloading): 같은 이름의 메서드를 매개변수에 따라 다르게 정의
  • 오버라이딩(Overriding): 부모 클래스의 메서드를 자식 클래스에서 재정의
  • 인터페이스 활용: 다형성을 극대화하여 유연한 코드 작성 가능

2. 추상 클래스와 인터페이스

1. 추상 클래스(Abstract Class)

  • abstract 키워드를 사용하여 선언
  • 객체를 직접 생성할 수 없고, 반드시 상속하여 사용
  • 일부 구현된 메서드를 포함할 수 있음
abstract class Animal {
    abstract void makeSound(); // 추상 메서드
    void sleep() {
        System.out.println("잠자는 중...");
    }
}

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

2. 인터페이스 (Interface)

  • interface 키워드를 사용하여 선언
  • 모든 메서드는 기본적으로 public abstract
  • 다중 구현이 가능하여 유연성이 높음
interface Animal {
    void makeSound();
}

class Cat implements Animal {
    public void makeSound() {
        System.out.println("야옹!");
    }
}

3. 오버로딩과 오버라이딩 (메서드 다형성)

1. 오버로딩 (Overloading)

같은 클래스 내에서 메서드 이름은 같지만 매개변수가 다를 경우 사용됩니다.

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

2. 오버라이딩 (Overriding)

부모 클래스의 메서드를 자식 클래스에서 재정의하는 것을 의미합니다.

class Parent {
    void showMessage() {
        System.out.println("부모 클래스");
    }
}

class Child extends Parent {
    @Override
    void showMessage() {
        System.out.println("자식 클래스");
    }
}

4. 다형성을 활용한 설계 패턴

1. 팩토리 패턴 (Factory Pattern)

객체 생성을 캡슐화

interface Shape {
    void draw();
}

class Circle implements Shape {
    public void draw() {
        System.out.println("원을 그립니다.");
    }
}

class ShapeFactory {
    static Shape getShape() {
        return new Circle();
    }
}

2. 전략 패턴 (Strategy Pattern)

동적으로 알고리즘을 변경 가능

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println(amount + "원을 신용카드로 결제합니다.");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println(amount + "원을 PayPal로 결제합니다.");
    }
}

class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

3. 템플릿 메서드 패턴 (Template Method Pattern)

상위 클래스에서 알고리즘의 구조를 정의하고, 하위 클래스에서 일부를 구현

abstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    public final void play() {
        initialize();
        startPlay();
        endPlay();
    }
}

class Football extends Game {
    void initialize() { System.out.println("축구 게임 초기화"); }
    void startPlay() { System.out.println("축구 경기 시작"); }
    void endPlay() { System.out.println("축구 경기 종료"); }
}

4. 어댑터 패턴 (AdapterPattern)

서로 다른 인터페이스를 변환하여 호환 가능하게 만듦

interface MediaPlayer {
    void play(String audioType, String fileName);
}

class Mp3Player implements MediaPlayer {
    public void play(String audioType, String fileName) {
        System.out.println("MP3 파일 재생: " + fileName);
    }
}

class MediaAdapter implements MediaPlayer {
    AdvancedMediaPlayer advancedMusicPlayer;

    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer = new Mp4Player();
        }
    }

    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer.playMp4(fileName);
        }
    }
}

interface AdvancedMediaPlayer {
    void playMp4(String fileName);
}

class Mp4Player implements AdvancedMediaPlayer {
    public void playMp4(String fileName) {
        System.out.println("MP4 파일 재생: " + fileName);
    }
}

5. 디코레이터 패턴 (Decorator Pattern)

동적으로 객체의 기능을 확장

interface Coffee {
    String getDescription();
    int cost();
}

class BasicCoffee implements Coffee {
    public String getDescription() { return "기본 커피"; }
    public int cost() { return 3000; }
}

class MilkDecorator implements Coffee {
    private Coffee coffee;
    
    public MilkDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    public String getDescription() {
        return coffee.getDescription() + ", 우유 추가";
    }

    public int cost() {
        return coffee.cost() + 500;
    }
}
728x90
반응형

'이것 저것 개발 공부 > JAVA' 카테고리의 다른 글

[Java] 예외처리  (0) 2025.03.01
[Java] 제네릭스와 컬렉션  (1) 2025.02.28
[Java] 상속  (0) 2025.02.28
[Java] 객체 배열  (0) 2025.02.27
[Java] 클래스와 객체  (2) 2025.02.27
728x90
반응형

1. 상속(Inheritance)이란

상속(Inheritance)이란 객체 지향 프로그래밍(OOP)에서 기존 클래스의 속성과 메서드를 새로운 클래스에서 재사용할 수 있도록 해주는 기능입니다. 이를 통해 코드의 중복을 줄이고 유지보수성을 높일 수 있습니다.

1. 상속의 주요 특징

  • 부모 클래스(상위 클래스)의 기능을 자식 클래스(하위 클래스)가 물려받음
  • extends 키워드를 사용하여 상속 구현
  • 코드 재사용성과 확장성이 높아짐
  • 단일 상속만 지원 (Java에서는 다중 상속이 불가능함)

2. 상속의 키워드

1. extends

class Parent {
    void show() {
        System.out.println("부모 클래스의 메서드");
    }
}

class Child extends Parent {
    void display() {
        System.out.println("자식 클래스의 메서드");
    }
}

public class InheritanceExample {
    public static void main(String[] args) {
        Child child = new Child();
        child.show(); // 부모 클래스의 메서드 호출
        child.display(); // 자식 클래스의 메서드 호출
    }
}

2. super

class Parent {
    String message = "부모 클래스";
}

class Child extends Parent {
    void printMessage() {
        System.out.println(super.message); // 부모 클래스의 변수 호출
    }
}

3. this

자기 자신의 인스턴스를 참조할 때 사용합니다.

3. 상속의 특징과 장점

  • 코드 재사용성: 기존 코드를 재활용하여 개발 시간을 단축
  • 유지보수 용이: 공통된 코드 수정 시 한 곳에서 변경 가능
  • 확장성: 기존 클래스의 기능을 확장하여 새로운 기능 추가 가능

4. 상속의 예제 코드

class Animal {
    void makeSound() {
        System.out.println("동물이 소리를 냅니다");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("멍멍!");
    }
}

public class InheritanceExample {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound(); // 부모 클래스의 메서드
        dog.bark(); // 자식 클래스의 메서드
    }
}

5. 상속과 다형성의 관계

class Parent {
    void display() {
        System.out.println("부모 클래스");
    }
}

class Child extends Parent {
    @Override
    void display() {
        System.out.println("자식 클래스");
    }
}

public class PolymorphismExample {
    public static void main(String[] args) {
        Parent obj = new Child(); // 업캐스팅 (Upcasting)
        obj.display(); // 자식 클래스의 display()가 실행됨
    }
}
728x90
반응형

'이것 저것 개발 공부 > JAVA' 카테고리의 다른 글

[Java] 제네릭스와 컬렉션  (1) 2025.02.28
[Java] 다형성  (1) 2025.02.28
[Java] 객체 배열  (0) 2025.02.27
[Java] 클래스와 객체  (2) 2025.02.27
[Java] 배열  (0) 2025.02.27
728x90
반응형

객체 배열이란

래퍼런스 변수에 대한 배열로 동일한 타이의 여러 인스턴스들을 배열로 관리할 수 있다.

Car[] carArray = new Car[5];
carArray[0] = new Car("페라리", 300);
carArray[1] = new Car("람보르기니", 350);
carArray[2] = new Car("롤스로이스", 250);
carArray[3] = new Car("부가티베이론", 400);
carArray[4] = new Car("포터", 500);

for (int i = 0; i < carArray.length; i++) {
	carArray[i].driveMaxSpeed();
}

/*
페라리이(가) 최고시속 300km/h로 달려갑니다.
람보르기니이(가) 최고시속 350km/h로 달려갑니다.
롤스로이스이(가) 최고시속 250km/h로 달려갑니다.
부가티베이론이(가) 최고시속 400km/h로 달려갑니다.
포터이(가) 최고시속 500km/h로 달려갑니다.
*/
728x90
반응형

'이것 저것 개발 공부 > JAVA' 카테고리의 다른 글

[Java] 다형성  (1) 2025.02.28
[Java] 상속  (0) 2025.02.28
[Java] 클래스와 객체  (2) 2025.02.27
[Java] 배열  (0) 2025.02.27
[Java] 제어문  (0) 2025.02.27

+ Recent posts