C언어에 이어 JAVA 부분입니다.


3. 자바

01. 자바 기본 구조

  • Java에서 모든 소스 코드는 클래스 단위로 구성
  • 프로그램은 public static void main부터 시작

클래스(Class)
객체 지향 관점에서 객체(Object)를 정의하는 틀로서 많은 객체 지향 프로그래밍 언어의 기본 구조로, 변수(Variable)메서드(Method)로 구성

public class Test {
  public static void main(String[] args){
    System.out.println("Hello"); // Hello
  }
}

02. 자료형

1) 자료형의 유형

유형설명선언 형식크기
문자형(Character)- 문자 하나를 저장
- 메모리에 저장은 숫자로
char1
문자열형(String)- 문자 여러 개를 저장String
정수형(Integer)- 정숫값을 저장int4
부동 소수점
(Floating Point)
- 소수점을 포함하는 실숫값 저장float, double
논리형(Logical; Boolean)- 변수의 참(true), 거짓(false)을 나타냄boolean

03. 변수 ⭐⭐

1) 변수 유효범위(Variable Scope)

① 클래스 변수(Class Variable)

  • 클래스 블록에 선언하는 변수
  • 클래스가 시작되면 변수가 생성되고, 클래스가 종료되면 변수 소멸
  • 클래스 변수는 클래스 내에서 사용할 수 있음
public class Test {
  int a = 5;
  void fn(){
    a = a + 3;
  }
  public static void main(String[] args){
    Test s = new Test();
    s.a = s.a + 5;
    s.fn();
    System.out.println(s.a); // 13
  }
}

② 지역 변수(Local Variable)

  • 블록 내에서 선언하는 변수
  • 블록이 시작되는 부분에 바로 선언해주어야 하고, 중괄호가 닫히는 시점에 소멸
  • 지역 변수는 해당 블록 안에서만 사용할 수 있음
public class Test {
  public static void main(String[] args){
    int a = 3;
    System.out.println(a); // 3
  }
}

③ static 변수

  • 프로그램이 시작되면 변수가 생성되고, 프로그램이 종료되면 변수가 소멸
  • static 변수는 프로그램 전체에서 사용할 수 있음
public class Test {
  static int count = 0;
  }
  public static void main(String[] args){
    Test s = new Test();
    s.count++;
    System.out.println(s.count); // 1
    s.count++;
    System.out.println(s.count); // 2
  }
}

04. 배열 ⭐⭐⭐

1) 배열 선언

① 1차원 배열 선언

구분선언
초깃값이 없는 경우자료형 []배열명 = new 자료형[배열_요소_개수];
자료형 배열명[] = new 자료형[배열_요소_개수];
초깃값이 있는 경우자료형 []배열명 = {초깃값};
  • 배열 요수 개수에 정의된 숫자만큼 같은 타입의 데이터 공간이 선언
  • 배열 요소 개수를 명시하지 않고 초깃값이 정의되어 있을 경우 초깃값 개수만큼 공간이 선언
  • 자바에서 배열의 크기를 구할 때는 length 속성을 사용
public class Test {
  public static void main(String[] args){
    int []a = new int[3];
    System.out.println(a.length); // 3
  }
}

② 2차원 배열 선언

구분선언
초깃값이 없는 경우자료형 [][]배열명 = new 자료형[행의 개수][열의 개수];
자료형 배열명[][] = new 자료형[행의 개수][열의 개수];
초깃값이 있는 경우자료형 [][]배열명 = {{초깃값}, {초깃값}, ··· };
public class Test {
  public static void main(String[] args){
    int[][] a = new int[3][2];
    System.out.println(a.length); // 3
    System.out.println(a[0].length); // 3
  }
}
public class Test {
  public static void main(String[] args){
    int[][] a = {{1, 2}, {3}, {4, 5, 6}};
    System.out.println(a.length); // 3
    System.out.println(a[0].length); // 2
    System.out.println(a[1].length); // 1
    System.out.println(a[2].length); // 3 
  }
}

05. 표준 입출력 함수 ⭐⭐

1) 표준 출력 함수

함수설명
System.out.print()개행을 하지 않는 출력함수
System.out.println()개행을 하는 출력함수
System.out.printf()C 언어처럼 변수를 출력할 수 있는 출력 함수

2) 표준 입력 함수

  • readLine은 입력장치(키보드)로부터 라인 전체를 읽는 표준 입력 함수
System.in.readLine()
import java.io.BufferedReader; // BufferedReader 사용 
import java.io.InputStreamReader; // InputStreamReader 사용
import java.io.IOException; // IOException 사용

public class Test {
  public static void main(String[] args) throws IOException{ // 입력 시 예외처리
    String a = null;
    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
    a = r.readLine(); // Hello
    
    System.out.println(a); // Hello
  }
}

06. 반복문 - for each 문 ⭐

1) for each 문

  • 배열이나 리스트의 크기만큼 반복하는데, 반복할 때마다 배열이나 리스트의 항목을 순차적으로 변수에 대입하는 반복문
for(제어변수 : 배열) {
  문장;
}
public class Test {
  public static void main(String[] args){
    String[] name = {"MINSU", "DANBI", "YUJIN"};
    for( String nm : name ){
      System.out.println(nm); // MINSU\nDANBI\nYUJIN
  }
}

07. 메서드 ⭐⭐

1) 사용자 정의 함수(메서드)

① 사용자 정의 함수(User-Defined Function)

  • 사용자가 직접 새로운 함수를 정의하여 사용하는 방법
  • 사용자 정의 함수에서 매개변수나 생성된 변수는 사용자 정의 함수가 종료되면 없어짐
자료형 함수명(자료형 변수명, ···){
  명령어;
  return 반환값;
}
public class Test {
  static char fn(int num){
    if(num % 2 == 0)
      return 'Y';
    else 
      return 'N';
  }
  public static void main(String[] args){
    char a = fn(5);
    System.out.print(a); // N
  }
}

2) static 메서드

  • 클래스가 메모리에 올라갈 때 자동적으로 생성되는 메서드
  • 인스턴스를 생성하지 않아도 호출이 가능

    인스턴스란 클래스로부터 만들어진 객체

class Test {
  static void print(){
    System.out.println("static method");
  }
}
public class TestMain {
  public static void main(String[] args){
    Test.print(); // static method
  }
}

→ ⭐ 자바는 클래스 이름과 파일 이름이 같아야 함. main 메서드가 포함된 클래스를 기준으로 하는데, 위 예제는 TestMain 클래스에 main 메서드가 포함되어 있으므로 TestMain.java 파일에 코드를 넣어서 실행해야 함

08. 클래스 ⭐⭐⭐

1) 클래스(class)

  • 객체 지향 프로그래밍(OOP; Object-Oriented Origrannubg)에서 특정 객체를 생성하기 위해 변수와 메서드를 정의하는 틀

2) 클래스 접근 제어자

① 클래스 접근 제어자(Access Modifier)

  • 지정된 클래스, 변수, 메서드를 외부(같은 패키지이거나 다른 패키지)에서 접근할 수 있도록 권한을 설정하는 기능

② 클래스 접근 제어자 종류

종류설명
public- 외부의 모든 클래스에서 접근이 가능한 접근 제어자
protected- 같은 패키지 내부에 있는 클래스, 하위 클래스(상속받은 경우)에서 접근이 가능한 접근 제어자
- 자기 자신과 상속받은 하위 클래스 둘 다 접근이 가능한 접근 제어자
default- 접근 제어자를 명시하지 않은 경우로 같은 패키지 내부에 있는 클래스에서 접근이 가능한 접근 제어자(java에만 존재)
private- 같은 클래스 내에서만 접근이 가능한 접근 제어자

⭐ 3) 클래스 정의

  • 클래스에서 변수는 변수 선언과 동일하고, 메서드는 사용자 정의 함수와 문법이 동일
  • 일반적으로 변수는 private 접근 제어자를 사용하여 외부에서 접근하지 못하게 하며, 메서드는 외부에 공개할 것만 public 접근 제어자를, 그렇지 않으면 protectedprivate 접근 제어자를 사용하여 정보은닉을 함
public class 클래스명{
  private 자료형 변수명;
  public 반환_자료형 메서드명(자료형 변수명, ···){
    명령어;
    return 반환값;
  }
}

⭐ 4) 클래스의 변수 생성

  • 클래스는 객체를 생성하기 위해 변수와 메서드를 정의하는 틀이므로 실제 변수에 들어갈 인스턴스를 new 키워드로 생성해주어야 함
  • 변수를 이용해 클래스의 메서드에 접근
클래스명 변수명 = new 클래스명(파라미터);
변수명.메서드명();

5) 클래스 this

  • this는 현재 객체를 가리키는 키워드
  • 클래스 내부의 변수와 메서드를 가리킬 수 있음
this.변수;
this.함수(매개변수);
class Test {
  private int a;
  public void setA(int a){
    this.a = a;
  }
  public int getA(){
    return a;
  }
  public static void main(String[] args){
    Test tes = new Test();
    tes.setA(5);
    System.out.print(tes.getA()); // 5
  }
}

6) 생성자(Constructor) ⭐

  • 해당 클래스의 객체가 생성될 때 자동으로 호출되는 특수한 종류의 메서드
  • 생성자는 일반적으로 클래스의 멤버 변수를 초기화하거나 클래스를 사용하는 데 필요한 설정이 필요한 경우 사용
  • 생성자는 클래스 명과 동일한 메서드명을 가지고, 반환 값이 없음
  • 생성자가 없을 경우 public 클래스명(){} 이라는 아무 일도 하지 않는 생성자가 있는 것처럼 동작
구분코드
생성자 정의public class 클래스명{
public 클래스명(매개변수){
명령어; } }
생성자 호출클래스명 클래스변수 = new 클래스명(매개변수);

7) 소멸자(Destructor) - finalize 메서드

  • finalize 메서드는 객체의 수명이 끝났을 때 객체를 제거하기 위한 목적으로 사용되는 메서드
  • 반환 값이 없음
구분코드
소멸자 정의public class 클래스명{
public void finalize(매개변수){
명령어; } }
생성자 호출클래스변수.finalize(매개변수);
class Test {
  public Test(){
    System.out.print("A");
  }
  public Test(int a){
    System.out.print("B: "+a);
  }
  public void finalize(){
    System.out.print("C");
  }
  public void fn(){
    System.out.print("D");
  }
  public static void main(String[] args){
    Test tes1 = new Test(); // A
    Test tes2 = new Test(5); // B: 5
    tes1.fn(); // D
    tes1.finalize(); // C
  }
}

09. 클래스 상속 ⭐⭐⭐

1) 클래스 상속(Inheritance)

  • 상속은 어떤 객체가 있을 때 그 객체의 변수와 메서드를 다른 객체가 물려받는 기능
  • 자식 클래스를 생성하면 무조건 부모 클래스의 생성자를 실행한 후에 자식 클래스의 생성자를 실행

⭐ 2) 상속 문법

class 부모_클래스명{ // 슈퍼 클래스
}
class 자식_클래스명 extends 부모_클래스명{ // 하위 클래스, 서브 클래스
}
class A {
  public void fnA(){
    System.out.print("A");
  }
}
class B extends A{
  public void fnB(){
    System.out.print("B");
  }
}
public class Test {
  public static void main(String[] args){
    B b = new B();
    b.fnA(); // A
    b.fnB(); // B
  }
}

→ ⭐ 자바는 자식 클래스를 생성하면 부모 클래스 생성자를 먼저 방문하지만, 파이썬자식 클래스의 생성자만 방문

3) 오버로딩(Overloading)

  • 동일 이름의 메서드를 매개변수만 다르게 하여 여러 개 정의할 수 있는 기능
    • 메서드 이름이 같아야 함
    • 매개변수 개수가 달라야 함
    • 매개변수 개수가 같을 경우 데이터 타입이 달라야 함
    • 반환형은 같거나 달라도 됨
class A {
  public void fn(){
    System.out.println("A");
  }
  public void fn(int i){
    System.out.println(i);
  }
  public void fn(double d){
    System.out.println(d);
  }
  public int fn(int a, int b){
    return a+b;
  }
}
public class Test {
  public static void main(String[] args){
    A a = new A();
    a.fn(); // A
    a.fn(7); // 7
    a.fn(10.0); // 10.0
    System.out.print(a.fn(2, 3)); // 5
  }
}

4) 오버라이딩(Overriding)

  • 하위 클래스에서 상위 클래스 메서드를 재정의할 수 있는 기능
    • 오버라이드하고자 하는 메서드가 상위 클래스에 존재하여 함
    • 메서드 이름은 같아야 함
    • 메서드 매개변수 개수, 데이터 타입이 같아야 함
    • 메서드 반환형이 같아야 함
class 부모_클래스명{
  public 반환_자료형 메서드명(자료형 변수명){ }
}
class 자식_클래스명 extends 부모_클래스명{
  public 반환_자료형 메서드명(자료형 변수명){ 
    // 부모 클래스의 메서드명, 매개변수가 동일해야 함
  }
}
class A {
  public void fn(){
    System.out.println("A");
  }
}
class B extends A {
  public void fn(){
    System.out.println("B");
  }
}
public class Test {
  public static void main(String[] args){
    A a = new B(); // B의 생성자 B()와 A의 생성자 A()를 호출해야 하지만 둘 다 없으므로 아무 일 X
    a.fn(); // B
  }
}

A a = new B();다형성(polymorphism)의 예로, 부모 클래스 A의 참조 변수가 자식 클래스 B의 인스턴스를 참조할 수 있음을 보여줌

  • 생성자 vs 오버라이딩 : 생성자는 클래스명과 동일한 이름의 메서드, 오버라이딩은 부모, 자식 간 동일한 이름의 메서드
class Parent {
  public Parent(){
    System.out.println("A");
  }
  public void fn(){
    System.out.println("B");
  }
}
class Child extends Parent {
  public Child(){
    System.out.println("C");
  }
  public void fn(){
    System.out.println("D");
  }
}
public class Test {
  public static void main(String[] args){
    Child c = new Child(); // A\nC\n
    c.fn(); // D
}

5) 부모 클래스 접근

  • 자바는 super 키워드를 이용하여 상위 클래스의 변수나 메서드에 접근할 수 있음
super.메서드명();
class A {
  public void fn(){
    System.out.println("A");
  }
}
class B extends A {
  public void fn(){
    super.fn();
    System.out.println("B");
  }
}
public class Test {
  public static void main(String[] args){
    A a = new B(); 
    a.fn(); // A\nB\n
  }
}

10. 추상 클래스 ⭐⭐

1) 추상 클래스

  • 미구현 추상 메서드를 한 개 이상 가지며, 자식 클래스에서 해당 추상 메서드를 반드시 구현하도록 강제하는 기능
abstract class 추상_클래스명 { 
  abstract 자료형 메서드명(); // 메서드 내부는 정의하지 않음
}
class 자식_클래스명 extends 추상_클래스명{
  자료형 메서드명(){
    명령어; // 메서드를 상속받아 메서드 내부를 정의
  }
}

11. 인터페이스 ⭐

1) 인터페이스(Interface)

  • 자바의 다형성을 극대화하여 개발코드 수정을 줄이고 프로그램 유지보수성을 높이기 위한 문법(인터페이스는 일종의 추상 클래스)
  • 오직 추상 메서드상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않음
  • 인터페이스는 구현된 것은 아무것도 없고 밑그림만 그려져 있는 '기본 설계도'
interface 인터페이스_클래스명 {
  자료형 메서드명(); // 메서드 내부는 정의하지 않음
}
class 자식_클래스명 implements 인터페이스_클래스명{
  자료형 메서드명(){
    // interface의 메서드를 상속받아 내부를 정의
  }
}
interface A{
  void fn();
}
class B implements A {
  public void fn(){
    System.out.println("B");
  }
}
class C implements A {
  public void fn(){
    System.out.println("C");
  }
}
public class Test {
  public static void main(String[] args){
    A b = new B(); 
    A c = new C(); 
    b.fn(); // B
    c.fn(); // C
  }
}

12. 스레드 ⭐

1) 스레드

  • 프로세스보다 가벼운, 독립적으로 수행되는 순차적인 제어의 흐름이며, 실행 단위

2) 스레드 구현

① Thread 클래스 상속

  1. Thread 클래스 상속 부분
  • 스레드를 만들기 위해서는 Thread 클래스를 상속받고, run() 메서드에 스레드 동작 시 수행할 코드를 작성(run 메서드 오버라이딩)
class T_Test extends Thread{
  public void run(){
    // 스레드 동작 시 수행할 코드
  }
}

→ Thread 클래스의 run() 메서드를 상속받아 재정의

  1. Thread 클래스 호출 부분
  • 스레드 클래스를 생성하여 스레드 변수에 저장
    1) Thread 스레드변수 = new 상속받은스레드클래스();
    2) Thread 스레드변수 = new Thread(new 상속받은스레드클래스());
  • 스레드변수.start()를 통해 스레드의 run() 메서드를 실행
class T_Test extends Thread{
  public void run(){
    System.out.println("Run");
  }
}

public class Test {
  public static void main(String[] args){
    Thread t1 = new T_Test(); 
    Thread t2 = new Thread(new T_Test());
    
    t1.start();
    t2.start();
    System.out.println("Main");
  }
}

→ main 함수에서 t1.start(); 이후, t2.start();를 하면 main 함수와 t1 스레드, t2 스레드가 동시에 동작하게 되므로 출력 결과는 달라질 수 있음

② Runnable 인터페이스 상속

  1. Runnable 인터페이스 상속 부분
  • 스레드를 만들기 위해서는 Runnable 인터페이스 상속받고, run() 메서드에 스레드 동작 시 수행할 코드를 작성(run 메서드 오버라이딩)
class T_Test implements Runnable{
  public void run(){
    // 스레드 동작 시 수행할 코드
  }
}

→ Runnable 클래스의 run() 메서드를 상속받아 재정의

  1. Runnable 클래스 호출 부분
  • 스레드 클래스를 생성하여 스레드 변수에 저장
    1) Thread 스레드변수 = new Thread(new 상속받은스레드클래스());
  • 위 Thread와 마찬가지로 스레드변수.start()를 통해 스레드의 run() 메서드를 실행

13. 컬렉션 ⭐

1) 컬렉션 프레임워크(Collection Framework)의 개념


출처 : [IT 기술 면접] Java의 Collection Framework 이란?

  • 다수의 데이터를 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합
  • 자바에서는 컬렉션 프레임워크를 통해 모든 컬렉션 클래스와 인터페이스를 제공
  • ⭐ map은 Collection 인터페이스를 상속받고 있지 않지만 Collection으로 분류

2) 컬렉션 프레임워크 특징

  • 배열의 단점을 보완 : 배열(Array)의 단점을 보완하여 만들어진 클래스로, 메모리 낭비를 방지하고 동적인 크기 변경 가능
  • 자료구조의 구현 : 자료구조 형태인 List, Set, Map 등이 클래스로 구현
  • 일관된 인터페이스 : 대량의 데이터를 일관된 인터페이스로 제공하여 쉽고 효율적으로 프로그램 작성 가능

3) 컬렉션 프레임워크의 구조

  • 자바에서 컬렉션 프레임워크는 인터페이스로 List, Set, Map 등을 제공
  • ⭐ Vector와 Hashtable의 경우 컬렉션 프레임워크의 명명법을 따르지 않음 → 가능하면 Vector 대신 ArrayList를, Hashtable 대신 Hashmap 사용을 권장
인터페이스구현 클래스특징
ListLinkedList
ArrayList
중복이 가능하고, 순서가 있는 데이터의 집합
SetHashSet
TreeSet
중복이 불가능하고, 순서가 없는 데이터의 집합
MapHashtable
HashMap
TreeMap
<키, 값>의 구조로 키는 중복이 불가능하고 값은 중복이 가능한 데이터의 집합

14. 예외 처리 ⭐

1) 예외 처리(Exception Handling)

  • 프로그램이 동작 중에 의도하지 않은 비정상적인 동작을 처리
구문내용
try {
명령문;
}
catch ( 예외처리명 ) {
예외처리_명령문;
}
finally {
명령문;
}
- try 다음에 수행할 명령문에서 예외가 발생하면 catch에서 예외를 처리
- catch는 하나 이상 작성하며, 상황에 맞는 예외처리가 수행됨
- finally 문장은 예외처리가 끝나고 받드시 실행되어야 하는 명령문을 수행함
public class Test {
  public static void main(String[] args){
    try {
      int a = 4/0;
    }
    catch (Exception e) {
      System.out.println(e.getMessage()); // /by zero(0으로 나눌 수 없어 예외 발생)
    }
    finally {
      System.out.println("Finally");
    }
  }
}

2) throw

  • 의도적으로 예외를 던지는 예약어
  • 컴파일에는 문제가 없지만 런타임에 발생된 에러를 처리하기 위해 사용
public class Test {
  public static void main(String[] args){
    try {
      throw new Exception();
    }
    catch (Exception e) {
      System.out.println("강제 예외 발생"); 
    }
  }
}

⭐ 3) throws

  • 메서드에서 발생하는 예외를 던지는 예약어
접근제어자 자료형 메서드명(매개변수) throws 예외처리명{
  명령문;
public class Test {
  public void divide(int a, int b) throws Eception{
    System.out.println(a/b); 
  }
  public static void main(String[] args){
    try {
      a.divide(4, 0);
    }
    catch (Exception e) {
      System.out.println(e.getMessage()); // /by zero
    }
  }
}
profile
이세계 개발자입니다.

0개의 댓글