[JAVA] 기본 개념 및 JVM, 실행, 변수의 타입

dejeong·2024년 9월 6일
0

JAVA

목록 보기
4/24
post-thumbnail

Java LTS (Long-Term Support) 버전

LTS 버전은 장기간 지원되며, 안정성과 호환성을 중시하는 프로젝트에 적합

  • Java 8: 초기 릴리스는 2014년으로, 여전히 많은 레거시 시스템에서 사용
  • Java 17: 2021년에 릴리스된 LTS 버전으로, 주요 기업들이 이 버전으로 업그레이드하고 있다.
  • Java 21: 2023년에 릴리스된 최신 LTS 버전으로, 새로운 기능과 최적화가 포함되어 있다.

자바의 특징

  • 객체 지향 언어이다.
  • 메모리를 자동으로 관리해준다.
  • 풍부한 라이브러리
  • 운영체제에 독립적

패키지(Package)

Java에서의 패키지는 파일 시스템의 폴더와 같으며, 클래스를 논리적으로 묶어 관리하는 단위


Main Method (main(String[] args))

main 메서드는 Java 프로그램의 시작점으로 프로그램이 실행될 때, main 메서드 안의 코드가 실행된다.

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

위 코드에서 System.out.println("Hello World");는 메인 메소드 내에서 실행된다.


args = 아규먼트 (Arguments)

args매개변수로, 프로그램이 실행될 때 외부에서 전달되는 값을 의미한다.
이를 통해 프로그램은 외부 입력값을 처리할 수 있다.


자바에서 메모리 관리: 가비지 컬렉터 (Garbage Collector)

Java는 가비지 컬렉터(GC)를 사용하여 메모리를 자동으로 관리한다.
더 이상 참조되지 않는 객체를 자동으로 메모리에서 제거함으로써 메모리 누수를 방지한다.


Java의 운영체제 독립성

Java는 "Write Once, Run Anywhere"라는 슬로건의 취지에 맞게 JVM(Java Virtual Machine)을 통해 운영체제에 독립적으로 동작한다. 즉, 동일한 Java 코드를 작성하면, 어떤 운영체제에서든 실행이 가능하다.
이는 자바의 가장 큰 장점 중 하나로, 다양한 플랫폼에서 동일한 프로그램을 실행할 수 있게 해준다.

운영체제가 독립적이지 않다?

종속되어 있다는 것으로 운영체제마다 프로그램이 달라야 된다.
java는 jvm이라는 가상 머신이 있기 때문에
운영체제에 독립적이다 = 운영체제 상관없이 동일한 자바 코드로 사용할 수 있다.
독립적이지 않게 되면
git을 설치했을 때처럼 운영체제(맥, 윈도우)마다 다른 방식으로 진행했던 것을 생각하기
"Write Once, run anywhere"한번 작성하면 어디서든 실행된다는 특징 - 이 특징은 JVM 으로 실행된다.

⭐ JVM(Java Virtual Machine)

JVM은 Java 프로그램이 실행되는 가상 머신으로, Java의 운영체제 독립성을 가능하게 하는 핵심 요소
JVM은 Java 코드를 실행하는데 필요한 모든 기능을 제공한다.

  • 클래스 파일: JVM이 이해할 수 있는 바이트 코드가 포함된 파일
  • 컴파일 및 실행: Java 코드는 컴파일러를 통해 바이트 코드로 변환되며, JVM이 이를 실행한다.

JVM은 운영체제와 하드웨어 위에서 동작하며, Java 코드가 기계어로 변환되어 실행된다.

  • Runtime Data Area: 개발자가 작성한 변수, 클래스, 메서드 등의 정보가 저장되는 메모리 영역
  • Garbage Collector: Runtime Data Area에서 사용되지 않는 메모리를 자동으로 정리
  • Class Loader: 클래스 파일을 JVM이 이해할 수 있도록 메모리에 로드하는 역할

JVM의 주요 구성 요소

  1. Class Loader
    • 클래스 로더는 Java 프로그램에서 사용되는 클래스들을 동적으로 로드하는 역할을 한다.
      개발자가 작성한 클래스 파일을 JVM이 이해할 수 있도록 메모리에 로드하고, 이를 실행할 수 있게 준비한다.
  2. Runtime Data Area
    • 런타임 데이터 영역은 JVM이 프로그램을 실행하는 동안 사용하는 메모리 영역.
      이 영역에는 개발자가 작성한 변수, 클래스, 메서드 등의 정보가 저장된다.
  3. Execution Engine
    • 실행 엔진은 로드된 클래스 파일을 실제로 실행하는 역할을 한다.
      바이트 코드를 해석하고, 기계어로 변환하여 프로그램을 실행한다.
  4. Garbage Collector (GC)
    • 메모리 관리의 핵심 요소
      더 이상 사용되지 않는 객체를 자동으로 메모리에서 제거힌다. 이를 통해 메모리 누수를 방지하고, 시스템 자원을 효율적으로 관리한다.
  5. Java API & Libraries
    • JVM은 Java 표준 라이브러리(API)를 통해 다양한 기능을 제공
      이 라이브러리들은 클래스 로더를 통해 로드되며, 개발자가 손쉽게 사용할 수 있는 기능들을 제공한다.

JVM의 동작 과정

  1. Java 소스 코드 작성
    • 개발자는 사람에게 친숙한 형태의 Java 소스 코드를 작성한다.
      이 코드는 JVM이 직접 실행할 수 없습니다.
  2. 컴파일
    • Java 컴파일러(javac)는 소스 코드를 기계어가 아닌 바이트 코드(.class 파일)로 변환한다. 이 바이트 코드는 JVM이 이해할 수 있는 코드이다.
  3. 클래스 파일 로드
    • 컴파일된 클래스 파일은 JVM의 클래스 로더에 의해 메모리에 로드된다.
  4. 실행
    • 로드된 클래스 파일은 실행 엔진에 의해 해석되어, JVM 하단의 실제 운영체제와 하드웨어에서 동작하게 된다.
  5. 메모리 관리
    • 프로그램 실행 중 사용되지 않는 객체들은 가비지 컬렉터에 의해 메모리에서 제거되며, 이는 자동으로 관리된다.

자바 컴파일 및 실행

  • 컴파일: javac 명령어를 사용하여 Java 소스 코드를 클래스 파일로 변환할 수 있다.
  • 실행: 변환된 클래스 파일은 java 명령어로 실행된다.
javac HelloWorld.java
java HelloWorld

IDE에서는 이러한 작업이 Run 버튼으로 자동화된다.


표준 API 사용: import

Java에서 표준 API를 사용하려면 필요한 클래스를 import해야 한다.
클래스 파일을 확인하려면 Ctrl + 클릭으로 확인할 수 있다.

import java.util.Scanner;

제네릭 (Generics)

제네릭은 꺽쇠 괄호(<>) 안에 타입을 지정하는 기능으로, 타입 안정성과 재사용성을 제공한다.

List<String> list = new ArrayList<>();

실행문

실행문은 변수 선언, 값 저장, 메소드 호출 등을 포함하며, 코드가 실제로 수행되는 단위를 의미한다.

실행문은 세미콜론(;)으로 끝나야 한다.

[실행문의 종류]

  • 변수 선언문
  • 값 저장
  • 메소드 호출: System.out.println()
  • 제어문
int value = 10;   // 변수 선언문
value = 20;       // 값 저장
System.out.println(value);   // 메소드 호출
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
  • main : 메서드 블럭
  • HelloWorld : 클래스
  • void : 리턴되는 값이 없다는 의미
  • static : 정적 메서드, 정적 변수, 정적 클래스, 객체를 만들지 않아도 클래스 이름.메서드명으로 호출이 가능하다. 클래스의 객체 생성없이 정적 메서드를 호출할 수 있다.
  • HelloWorld.main : 메인 메서드가 정적 키워드가 붙었기 때문에 해당 방법으로 외부에서 호출을 해줄 수 있음, 근데 좋지 않은 예시임 외부에서 호출할 일이 거의 없기 때문 static의 역할에 대한 설명의 참고 정도
  • String[] args : 매게 변수, 외부에서 호출을 할 때 해당 타입으로 호출할 수 있도록 하는 것 자료형[] 변수이름 | 변수의 이름으로 값을 받을 수 있다는 의미

접근 제어자 (Access Modifier)

public은 접근 제어자로, 외부 클래스에서도 접근할 수 있는 클래스나 메서드를 정의한다.

  • 클래스 파일 안에는 public class가 반드시 하나만 있어야 한다.
  • 정적 메서드static 키워드를 사용하며, 클래스 이름을 통해 직접 호출할 수 있다.
  • return type이 없을 경우 void를 사용한다.
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

변수의 선언과 저장

변수는 하나의 값만 저장할 수 있는데, 변수의 타입에 따라서 여러 개의 값을 저장할 수도 있다.

자료형이라고도 부르고 타입이라고도 부른다. JVM에 스택이라는 영역에 값이 할당된 것
예약어를 사용하여 변수 선언을 하지 않도록 주의!

변수를 선언하고 사용하기 위해서는 초기화가 필요하다

// case 1
public static void main(String[] args) { // 메서드블록
      int value;
      int result = value + 10;
}

// case 2
public static void main(String[] args) { // 메서드블록
  int value;
  System.out.println(value);
}

value에 선언만 하고 값을 안주었기 때문에 컴파일 오류가 생긴다.
해결하기 위해서는 value를 선언할 때 초기값을 저장할 수 있도록 구문을 수정한다


변수의 사용 범위

변수는 선언된 블록 내에서만 사용 가능하다.

// 클래스 블록
public class Sample {
    public static void main(String[] args) { // 메서드블록
      int value = 0;
      System.out.println(value);

      if(true){
          double inner = 1.2;
          System.out.println("조건이 참");
      }
    }
}

위 코드에서 inner 변수는 if 블럭 바깥에서 사용할 수 없다.

// 클래스 블록
public class Sample {
    public static void main(String[] args) { // 메서드블록
      int value = 0;
      System.out.println(value);

      if(true){
          double inner = 1.2;
          System.out.println("조건이 참");
          
          for(int i = 1; i <= 10; i++){
              // inner 변수 사용 가능
          }
      }
    }
}

클래스명 규칙

메서드 블록

saveMerbersProfile - 회원정보를 저장하는 기능의 메서드
[메서드명을 작성하는 규칙]

  • 맨 앞에 '동사(save)'

Q. 회원정보를 조회하는 메서드 : get, find

1. 케밥 케이스 (Kebab Case)

  • 표기법: 단어 사이를 하이픈(-)으로 구분한다.
  • 예시: total-score
  • 사용 사례: 주로 URL이나 CSS 클래스 이름에서 사용한다.

2. 스네이크 케이스 (Snake Case)

  • 표기법: 단어 사이를 언더스코어(_)로 구분한다.
  • 예시: total_score
  • 사용 사례: 주로 Python 변수명이나 상수명에서 사용한다.

3. 카멜 케이스 (Camel Case)

  • 표기법: 첫 번째 단어는 소문자로 시작하고, 이후 단어들의 첫 글자를 대문자로 표기한다.
  • 예시: camelCase, userInformation
  • 사용 사례: 자바에서는 주로 메서드명이나 변수명에 사용한다.

4. 파스칼 케이스 (Pascal Case)

  • 표기법: 모든 단어의 첫 글자를 대문자로 표기한다.
  • 예시: PascalCase, AdminAccount, TotalScore
  • 사용 사례: 자바에서는 주로 클래스명이나 인터페이스명에 사용한다.

5. 코딩 컨벤션

  • 자바에서의 사용법:
    • 클래스명인터페이스명: 파스칼 케이스 사용
    • 메서드명변수명: 카멜 케이스 사용
  • 참고자료: 더 자세한 코딩 규칙은 Google 자바 스타일 가이드를 참고할 수 있다.

이러한 표기법을 통해 코드의 가독성을 높이고 일관성을 유지할 수 있다.


변수의 타입

변수를 선언하면 메모리에 저장 공간이 할당되며, 이 공간에 값을 저장할 수 있다. 저장 공간의 크기는 변수의 타입에 따라 달라지며, 이는 타입마다 점유하는 메모리 크기가 다르기 때문이다.

메모리와 비트

  • 1 byte = 8 bits로, 1 byte는 8자리의 비트로 구성된다.
  • 각 비트는 0 또는 1을 표현할 수 있으며, 이를 통해 2의 8승인 256가지의 값을 표현할 수 있다.
  • 예를 들어, 8비트로 표현할 수 있는 값의 범위는 0에서 255까지로, 이를 부호를 포함해 표현하면 128에서 127까지의 범위를 가지게 된다.

변수 타입과 저장 공간

  • 컴퓨터는 0과 1로 구성된 비트를 사용해 데이터를 저장한다.
  • 변수에 저장되는 값이 해당 타입의 최대 범위를 초과하면 오버플로우가 발생한다. 이 경우, 예상치 못한 결과나 쓰레기 값이 출력될 수 있다.
  • 따라서, 기본적으로 int 타입을 사용하며, 더 큰 값을 저장해야 할 경우 long 타입을 사용하는 것이 좋다.

주요 변수 타입과 특징

  • 정수형
    • byte: 1 byte 크기, -128 ~ 127 범위
    • short: 2 byte 크기, -32,768 ~ 32,767 범위
    • int: 4 byte 크기, -2,147,483,648 ~ 2,147,483,647 범위 (기본 정수형)
    • long: 8 byte 크기, 매우 큰 정수 범위 (-2^63 ~ 2^63-1)
  • 실수형
    • float: 4 byte 크기, 소수점 이하 약 7자리까지 표현 가능
    • double: 8 byte 크기, 소수점 이하 약 15자리까지 표현 가능 (기본 실수형)
  • 논리형
    • boolean: 1 bit 크기, true 또는 false만을 저장 (0 또는 1로 표현)

Java의 변수 타입은 크게 기본 타입(Primitive Type)참조 타입(Reference Type)으로 나뉜다.

  • 기본 타입: char, int, long, double, float, boolean 등이 있으며, 각 타입은 메모리에서 고정된 크기를 가진다.

    값의 종류기본 타입메모리 사용 크기저장되는 값의 범위
    정수byte1byte-128 ~ 127
    정수, 문자char2byte0 ~ 65535
    정수short2byte-32,768 ~ 32,767
    정수int4byte-2,147,483,648 ~ 2,147,483,647
    정수long8byte–9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
    실수float4byte3.4E+/-38(7개의 자릿수)
    실수double8byte1.7E+/-308(15개의 자릿수)
    논리형boolean1bytetrue, false
  • 참조 타입: 객체를 참조하는 변수 타입


숫자 타입의 범위와 오버플로우

타입의 크기에 따라 변수에 저장할 수 있는 값의 범위가 달라지며,
범위를 초과할 경우 오버플로우가 발생하여 예상치 못한 결과가 나올 수 있다.

public class GarbageValueExample {
    public static void main(String[] args) {
        byte a = 127;   // -128 ~ 127
        int b = 2147483647;   // +-20억의 숫자 범위

        a++;
        b++;
        System.out.println("a = " + a);   // 오버플로우 발생
        System.out.println("b = " + b);   // 오버플로우 발생
    }
}
0 a = -126
0 b = 128
1 a = -125
1 b = 129
2 a = -124
2 b = 130
3 a = -123
3 b = 131
4 a = -122
4 b = 132

a라는 변수는 byte타입이기 때문에 127이상의 값을 표현할 수 없다 그래서 결과 값에서는 예상할 수 없었던 쓰레기값이 들어가게 된다.


정수 타입 (byte, char, short, int, long)

byte (1byte) < char (2byte) < short (2byte) < int (4byte) < long (8byte)

char

보통 하나의 문자를 저장하는데 사용하는 타입
문자열을 선언하는 String타입과는 달리 char 타입은 작은 따옴표(’)를 사용한다.

public class CharVariableExample {
	public static void main(String[] args) {
		char c1 = 'A';            // 문자를 직접 저장
		char c2 = 65;            // 10진수로 저장
		char c3 = '\u0041';        // 16진수로 저장

		char c4 = '가';            // 문자를 직접 저장
		char c5 = 44032;        // 10진수로 저장
		char c6 = '\uac00';        // 16진수로 저장

		int unicode = c1;        // 유니코드 얻기

		System.out.println(c1);
		System.out.println(c2);
		System.out.println(c3);
		System.out.println(c4);
		System.out.println(c5);
		System.out.println(c6);
		System.out.println(unicode);
	}
}

int

int 정수형 타입 정수 연산을 위한 기본 타입으로 4byte이다.

public class IntVariableExample {
	public static void main(String[] args) {
		int result = 10 + 20;
		System.out.println(result);   // 연산 결과 30 출력 
	}
}

long

long 타입은 int보다 더 큰 범위의 정수를 표현할 수 있다.
기본적으로 int를 사용하지만, 더 큰 범위가 필요할 때 long을 사용한다.


public class VariableExample {
    // long 타입
    public static void main(String[] args) {
        int a = 1;
        int b = 10000000000; // 100억 입력 시 오류, L을 추가해도 오류가 생김, 값을 최종적으로 할당할 공간이 부족하기 때문(int로 선언됨)

        long longValue = 100; //(int -> long) 자동으로 형변환
        long longValue2 = 10000000000L; // 100억 컴파일러가 숫자만 들어있다면 기본적으로 int 형으로 생각함으로 int형이 아니라는 표시 "L"를 해주어야 한다.
    }
}

실수 타입 (float, double)

float (4byte) < double (8byte)
소수점이 있는 숫자를 말한다. Java에서 실수를 표현할 때는 floatdouble 타입을 사용
기본적으로 double 타입을 사용하며, float을 사용할 때는 f 또는 F를 붙여야 한다.

주로F를 사용한다. float 타입에 실수값을 쓰면 컴파일러는 double 타입으로 기본적으로 간주하기 때문에 F를 붙혀주어야 한다. -> 컴파일 에러가 나게 됨

public class VariableExample {
    public static void main(String[] args) {
        float floatValue = 1.01234F;   // F는 컴파일러에 알려주기 위한 구분자이고, 출력될 때는 F를 제외한 값이 전달된다. 

        double doubleValue = 1.1234;

        System.out.println("floatValue = " + floatValue);
        System.out.println("doubleValue = " + doubleValue);
    }
}

// 정밀도 테스트
float floatValue2 = 0.1234567890123456789F;
double doubleValue2 = 0.1234567890123456789; // 연산을 해야되고, 소수점 자리수를 보존해야 된다면 double을 사용하는 게 좋음

System.out.println("floatValue2 = " + floatValue2);
System.out.println("doubleValue2 = " + doubleValue2);
floatValue2 = 0.12345679
doubleValue2 = 0.12345678901234568

논리 타입 (boolean)

boolean 타입은 논리 값을 저장하며, true 또는 false만을 가질 수 있다.
상태값에 따라 조건문과 제어문의 실행 흐름을 변경하는데 주로 이용된다.

1 : true
0 : false

boolean isActive = true;
if (isActive) {
    System.out.println("Active!");
}

profile
룰루

0개의 댓글