Java/[도서] 자바의 정석

자바, 변수, 기본형과 참조형, 상수와 리터럴, 진법, 형변환 (1/8)

Lea Hwang 2022. 11. 24. 21:58

토이 프로젝트를 하면서 자바에 대해 중간중간 개념이 헷갈리는 부분이 보였습니다. 예전에 자바의 정석을 1독 한 적 있지만 다시 읽고 처음부터 정리하는 것이 너무 오래 걸릴 것 같아 항상 미뤄왔었습니다.

 

그러다 우연히 잘 정리된 GitHub repository가 있어 많은 도움을 받았습니다.

이번 시리즈는 하나하나 깊게 개념을 공부해서 정리한 것이 아닌  크게 크게 어떤 개념들이 있는지 마치 도서의 목차를 머릿속에 넣는다는 느낌으로 진행하고자 합니다.

참고한 repository : https://github.com/vividswan/The_Essence_of_Java_Book_Study

 


 

자바(Java Programming Language)란? 

  • 썬 마이크로시스템즈에서 개발 후 1996년 1월 공식 발표
  • 운영체제 독립적
  • 객체지향과 c++와 같은 다른 언어의 장점을 채택 (쉽고 간결한 표현)
  • 2010년 오라클사가 인수

 

자바 언어의 특징

  • 운영 체제에 독립적
    • 프로그램은 운영체제에 독립적
    • 이를 해석하는 JVM은 운영체제에 종속적
      • 여러 운영체제엔 서로 다른 버전의 JVM 제공
  • 객체지향언어
    • 순수한 객체지향언어
    • 상속, 캡슐화, 다형성이 적용
  • 자동 메모리 관리(Garbage Collection)
    • 가비지 컬렉터가 자동으로 메모리 관리 → 프로그래머는 프로그래밍에 더 집중 가능해짐
  • 네트워크와 분산처리 지원
    • 다양한 네트워크 프로그래밍 라이브러리 Java API 지원
  • 멀티 스레드 지원
    • 관련된 라이브러리 제공 (Java API)
    • 자바 인터프리터가 여러 쓰레드의 스케줄링 담당
  • 동적 로딩 (Dynamic Loading) 지원
    • 실행 시에 모든 클래스가 로딩되는 게 아닌 필요한 시점에 클래스 로딩
    • 일부 클래스 변경 시 or 애플리케이션의 변경 시 비교적 적은 작업으로 처리

JVM (Java Virtual Machine)

  • 자바를 실행하기 위한 가상 기계
  • 자바로 작성된 애플리케이션은 모두 JVM에서만 실행
    • 실행을 위해 반드시 JVM이 필요

 

일반 애플리케이션과 비교

일반 애플리케이션

일반 애플리케이션 ↔ OS ↔ 컴퓨터

다양한 OS용 JVM

JAVA 애플리케이션 ↔ Windows용 JVM ↔ OS(Window) ↔ 컴퓨터
JAVA 애플리케이션 ↔ Macintosh용 JVM  ↔ OS(Macintosh)  ↔ 컴퓨터
JAVA 애플리케이션   ↔ Linux용 JVM  ↔ OS(Linux)  ↔ 컴퓨터

  • 일반 애플리케이션은 OS 종속적
  • 자바 어플리케이션은 JVM이 OS 종속적
    • 자바 어플리케이션은 OS와 하드웨어에 독립적
      • Write once, run anywhere.

 

자바로 프로그램 작성하기

Hello.java

  • 클래스의 이름과 .java 파일의 이름이 대소문자까지 정확히 같아야 함
  • 순서
    • Hello.java → (javac.exe가 컴파일) → Hello.class → (java.exe로 실행) → 프로그램
  • 자바의 모든 코드는 반드시 클래스 안에 작성
    • 클래스들이 모여 애플리케이션
  • public static void main(String[] args)는 main 메서드 선언부
    • 항상 똑같이 적어주어야 함
    • 하나의 Java 애플리케이션엔 main 메서드가 반드시 필요
  • 하나의 소스 파일에 여러 가지 클래스도 가능
    • public class의 이름과 소스 파일 이름이 일치해야 된다.
    • public class가 없다면 어떤 클래스든 괜찮음
    • 소스와 달리 클래스 파일은 class마다 하나씩 생성

 

자주 발생하는 에러와 해결 방법

  • cannot find symbol 또는 cannot resolve symbol
    • 지정된 변수나 메서드를 찾을 수 없을 때
  • ';' expected
    • ;이 필요한 곳에 없을 때
    • 자바는 모든 문장의 끝에 세미콜론 필요
  • Exception in thread "main" java.lang.NoSuchMethodError: main
    • main 메서드를 찾을 수 없을 때
    • 클래스에 main 메서드가 정의되어 있는지 확인
  • Exception in thread "main" java.lang.NoSuchClassError: Hello
    • Hello라는 클래스를 찾을 수 없을 때
    • 클래스 Hello의 철자와 패스 설정 확인
  • illegal start of expression
    • 문장에 문법적 오류가 있을 때
    • 괄호 확인
    • 접근 제어자 키워드 확인
  • class, inteface, or enum expected
    • class, inteface, or enum에 대한 오류
    • 괄호의 개수가 일치하지 않을 때
  • 에러가 발생했을 때 처리 순서
    • 에러 메시지를 읽고 해당 코드 살펴보기
      • 이상 없을 시 그 주변 코드도 살펴보기
    • 그래도 해결이 안 되면 기본적인 부분들 확인
    • 의심이 가는 부분은 주석 처리 or 테스트

 

자바 프로그램의 실행 과정

  • 프로그램의 실행에 필요한 클래스(*.class)를 로드
  • 클래스 파일 검사
    • 파일 형식, 악성코드 체크
  • 지정된 클래스에서 main 메서드 호출

 

주석(comment)

  • 주석의 종류
    •  /* 여러 줄 주석 */
    • // 한 줄 주석
  • 큰따옴표 안에 있을 땐 주석이 아닌 문자열로 인식하므로 주의

 

 

변수(variable) 

변수란?

단 하나의 값을 저장할 수 있는 메모리 공간으로 새로운 값을 저장하면 기존의 값은 사라짐

 

변수의 선언

(변수 타입) (변수 이름);
  • 변수 타입은 저장될 타입
    • 자바는 정수형, 실수형, 문자형등의 기본 자료형 사용
  • 변수 이름은 메모리 공간에 붙은 이름
    • 저장된 값을 읽어올 때 사용
    • 서로 구별되어야 함
  • 선언 시 변수 타입에 알맞은 크기의 저장 공간이 확보

 

변수의 초기화

  • 초기화란 변수를 선언하고 처음으로 값을 저장하는 것
  • 초기화는 객체를 생성하는 작업이 아닌 객체안에 필요한 값이 다 연결되어있고 처음 제대로 일을 시작하는 과정으로 이해
  • 메모리는 여러 프로그램이 공유하는 자원이므로 필수
    • 알 수 없는 쓰레기 값이 남아있을 수도 있기 때문
    • 클래스 변수와 인스턴스 변수는 초기화 생략 가능
    • 지역 변수는 반드시 초기화를 해야 함
  • 대입 연산자 사용해서 오른쪽의 값을 왼쪽에 저장
  • 콤마로 여러 줄을 한 줄에 선언도 가능
int a;
int b;
int a, b;

int x = 0;
int y = 0;
int x = 0, y = 0;

 

덧셈 연산자는 두 값을 더하기도 하지만, 문자열과 숫자를 결합하기도 함

  • 문자열 :  큰따옴표("")로 묶은 연속된 문자
  • ex) System.out.println("x:" + 10) -> System.out.println("x:10")

 

변수의 명명 규칙

 

식별자란?
패키지, 클래스, 인터페이스, 메소드 또는 변수에 지정된 이름입니다.

 

 

식별자의 규칙

 

  • 대소문자 구분 & 길이 제한 X
  • 예약어는 사용 X
    • true는 X, True는 O
    • 예약어들은 클래스, 변수, 메서드의 이름으로 사용 X
  • 숫자로 시작 X
  • 특수문자는 '_'와 '&'만 허용

자바 프로그래머들에게 권장하는 규칙 (암묵적 약속)

  • 클래스 이름의 첫 글자는 항상 대문자
    • 클래스 이름은 ASCII 코드로 (유니코드를 인식하지 못하는 OS를 위해)
  • 여러 단어로 이루어진 이름은 단어의 첫 글자를 대문자
  • 상수의 이름은 모두 대문자 & 여러 단어일 시 '_'
    • ex) PI, MAX_NUMBER
  • 특별한 방식으로 식별자를 작성해야 할 땐 미리 규칙을 세워서 일관되게 적용할 것
    • coding convention
  • 변수의 이름은 짧으면 좋지만 길더라도 용도를 알기 쉽게 의미 있는 이름으로 할 것

 

기본형과 참조형

기본형 : 논리형(boolean), 문자형(char), 정수형(byte, short, int, long), 실수형(float, double)

 

참조형 : 객체의 주소를 저장, 8개의 기본형을 제외한 나머지

 

 

 

참조 변수를 선언하는 방법

클래스이름 변수이름;       ← 변수이름 자리가 참조변수

 

ex) Date today = new Date();

  • new의 생성 결과는 객체의 주소
  • 대입 연산자(=)에 의해 참조 변수 today에 객체의 주소가 저장

자료형 vs 타입

  • 타입이 자료형을 포함하는 넓은 의미
  • 참조형 변수는 타입을, 기본형은 자료형이란 용어를 사용

기본형

  • 논리형
    • boolean (true or false)
  • 문자형
    • char (단 하나의 문자를 저장하는 데 사용)
    • int형에 char형 변수를 대입 시 정수형으로 캐스팅할 것
    • 특수문자
      • \t(tab)
      • \b(백스페이스)
      • \f(form feed)
      • \n(new line)
      • \r(캐리지 리턴)
      • \\(역슬래쉬)
      • \`(작은따옴표)
      • \"(큰따옴표)
      • \u유니코드(16진수인 유니코드 문자)
  • 정수형
    • byte, short, int, long
  • 실수형
    • float, double 

정수에선 int를 CPU가 가장 효율적으로 처리

  • 메모리를 아끼기 위해선 byte나 short 사용

기본 자료형의 종류와 크기 (8bit가 1byte)

  • boolean → 1byte
  • char → 2byte 
  • byte → 1byte
  • short → 2byte
  • int → 4byte
  • long → 8byte
  • float → 4byte
  • double → 8byte

 

상수와 리터럴

상수

  • 변수와 마찬가지로 값을 저장할 수 있는 공간 & 한번 값을 저장하면 변경 X
  • final 키워드를 앞에 붙여줘야 함
  • JDK1.6부터 선언과 동시에 초기화하지 않아도 되지만 웬만하면 선언과 동시에 초기화할 것
  • 상수의 이름은 모두 대문자 (여러 단어의 경우 '_' 사용)
final int MAX_SPEEP = 100;

 

리터럴

  • 12, 123, 3.14, 'A'와 같은 값들이 리터럴
  • 리터럴은 보통 알고 있는 상수
변수 : 하나의 값을 저장하기 위한 공간
상수 : 값을 한 번만 저장할 수 있는 공간
리터럴 : 그 자체로 값을 의미하는 것
    int year = 2014;
    final int MAX_VALUE = 100;

    // 2014, 100 -> 리터럴
    // year -> 변수
    // MAX_VALUE -> 상수

 

 

상수가 필요한 이유

 

  • 리터럴에 의미 있는 이름을 붙여서 코드의 이해 및 수정을 쉽게 하기 위함

 

타입의 불일치

 

타입이 달라도 저장 범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 허용

  • 그 반대는 컴파일 에러

 

문자 리터럴과 문자열 리터럴

 

문자 리터럴 : 작은 따옴표로 문자 하나를 감싼 것

문자열 리터럴 : 큰 문자열로 감싼 것 (두 문자 이상은 문자열임)

  • 문자열 리터럴은 빈 문자열이 허용
    • 문자는 반드시 '' 안에 하나의 문자 필요
  • String name = "test"는 String name = new String("test")와 같음
  • 덧셈 연산자 사용 가능
    • 피연산자 모두 숫자일 땐 숫자를 더함
    • 어느 한쪽이라도 String 이면 나머지 한쪽도 String으로 변환 후 String 결합
    • 왼쪽에서 오른쪽 방향으로 수행하기 때문에 결합 순서에 따라 결과가 달라짐

 

 

printf()

 

println() 보다 값을 여러 형식으로 출력 가능

  • println()과 달리 줄바꿈이 없으므로 %n을 넣어줘야 한다.
    • OS마다 줄 바꿈 문자가 다를 수 있으므로 '\n'보다는 '%n'
  • 자주 사용되는 지시자
    • %b : 불리언 형식으로 출력
    • %d : 10진 정수의 형식으로 출력
    • %o : 8진 정수의 형식으로 출력
    • %x, %X : 16진 정수의 형식으로 출력
    • %f : 부동 소수점 형식으로 출력
    • %e, %E : 지수 표현식의 형식으로 출력
    • %c : 문자로 출력
    • %s : 문자열로 출력
  • 지시자 사이에 숫자를 추가하면 원하는 만큼의 출력 공간을 확보하거나 문자열의 일부만 출력
    • 실수형 일 땐 `%전체 자리.소수점 아래 자리f`
    • N : 최소 N글자 출력 공간 확보 (우측 정렬)
    • -N : 최소 N 글자 출력 공간 확보 (좌측 정렬)
    • . : 왼쪽에서 N 글자만 출력

 

 

화면에서 입력받기 - Scanner

 

  • import java.util.*; 
  • Scanner scanner = new Scanner(System.in); 으로 객체 생성
  • scanner.nextLine(); 을 통해 입력받은 내용을 저장
  • 파싱이 필요할 땐 nextInt나 nextFloat 사용

 

진법 

10진법과 2진법

  • 일상에서 자주 사용하는 것은 10진법
  • 컴퓨터는 1,0 (전기가 흐르거나, 흐르지 않거나) → 2진법
  • 2진법은 10진법에 비해 많은 자릿수가 필요

10진수 ↔ 2진수, 8진수, 16진수 변환 방법

  •  

 

형변환

변수 또는 상수의 타입을 다른 타입으로 변환하는 것

  • boolean을 제외한 나머지 7개의 기본형은 서로 형변환이 가능
  • 기본형과 참조형끼리는 형변환 X

자동 형변환

  • 대입이나 연산 시 컴파일러가 생략된 형변환을 자동으로 추가 (할당하는 타입이 클 경우)
  • 변수가 저장할 수 있는 값의 범위보다 더 큰 값을 저장할 땐 형변환 생략 시 에러
  • 서로 다른 두 타입 간의 덧셈에선 표현 범위가 더 넓은 타입으로 형변환
    • 값 손실의 위험을 줄이기 위해
  • 기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환이 규칙
    • byte → (short or char) → int → long → float → double

[참고 포스팅] 형변환 (문자형↔정수형↔실수형)

 

 

 

 

 

 

 

 

 

  •