[TIL] 자바 #1

Hyeonu_J·2022년 1월 3일
0
post-custom-banner

공부할 책 : 혼자 공부하는 자바

C언어랑 비슷하길래 몇몇내용 중략..! 쉽다쉬워 히히

자바란?

프로그래밍 언어로 전 세계적으로 다양한 분야에서 사용되고 있다.
안드로이드 폰에서 실행하는 앱 뿐만 아니라 웹사이트를 개발하는 핵심 언어로 사용되며, 모든 운영체제에서 실행 가능한 데스크톱 애플리케이션 개발에도 사용할 수 있다.

특징

모든 운영체제에서 실행 가능
윈도우에서 개발된 프로그램을 수정하지 않고 리눅스에서도 실행할 수 있다.
객체 지향 프로그래밍
객체 지향 프로그래밍 : 객체(부품)을 만들고, 이 객체들을 서로 연결해서 더 큰 프로그램을 완성하는 기법
메모리 자동 정리
자바는 메모리(RAM)를 자동 관리하므로, 개발자는 메모리를 관리하는 수고를 덜고 핵심 기능인 코드 작성에 집중할 수 있다.
무료 라이브러리 풍부
오픈 소스 라이브러리가 풍부해서 개발 기간을 단축해 준다.

자바 프로그램 개발 과정


.java 인 텍스트 파일을 생성하고 자바 언어로 코드를 작성한다.
이렇게 만들어진 자바 소스 파일을 컴파일러인 javac 명령어로 컴파일한다.
컴파일이 성공하면 확장명이 .class 인 바이트 코드 파일이 생성된다.

바이트 코드 파일은 완전한 기계어가 아니므로 바로 실행할 수 있는 파일이 아니다.
바이트 코드 파일을 완전한 기계어로 번역해서 실행하려면 java 명령어를 사용해야 한다.

자바 프로그램은 완전한 기계어가 아닌 바이트 코드 파일(.class)로 구성된다.
바이트 코드 파일은 운영체제에서 바로 실행할 수 없고, 자바 가상 기계 (JVM)이라는 번역기가 필요하다.

자바가 JVM을 사용하는 이유는 바이트 코드 파일을 다양한 운영체제에서 수정하지 않고 사용할 수 있도록 하기 위함이다. 이 특징이 자바 언어를 성공으로 이끌었다고 볼 수 있다.

프로젝트 생성 → 소스 파일 생성과 작성 → 바이트 코드 실행
아래는 이 과정을 진행한 모습이다.

프로그램 소스 분석


패키지 선언 : Hello.java 소스 파일을 보면 최상단에 package 키워드와 sec03이 명시되어 있다. Hello.java는 sec03.exam01 패키지에서 생성되었기 때문에 이와 같은 패키지 선언이 반드시 있어야 한다.

pacakage sec03.exam01;


클래스 선언부 : 중괄호 {} 블록의 앞부분인 public class Hello

공개 클래스 : public class

클래스 이름 : Hello

javac 명령어로 컴파일하면 클래스 이름에 .class 가 붙어 바이트 코드 파일이 생성된다.
Hello.class를 Hello 바이트 코드 파일이라 부르지 않고 Hello 클래스라고 간단히 부른다.
java 명령어로 바이트 코드 파일을 실행하려면 클래스 블록 내부에 다음과 같은 main() 메소드 블록을 가지고 있어야 한다.


메소드 선언부 : public static void main(String[] args)

메소드 이름 : 괄호() 바로 앞의 main

데이터 타입

자바의 타입은 크게 기본 타입과 참조 타입으로 분류된다.
두 변수의 차이점은 저장되는 값이다.

기본 타입

정수, 실수, 문자, 논리 리터럴을 저장하는 타입
변수를 선언하고 데이터를 저장할 수 있다.

기본 타입인 byte, char, short, int, long, float, double, boolean 변수는
실제 값을 변수 안에 저장한다.

예시 :

int age = 25;
double prince = 100.5;

참조 타입

객체의 번지를 참조하는 타입으로 배열, 열거, 클래스, 인터페이스를 말한다.

참조 타입인 배열, 열거, 클래스, 인터페이스 변수는 메모리의 번지를 변수 안에 저장한다.
번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라고 부른다.

예시 :

String name = "신용권";
String hobby = "독서";

메모리 사용 영역

JVM은 운영체제에서 할당받은 메모리 영역을 세부 영역(메소드,힙,JVM스택)으로 구분해서 사용한다.

메소드 영역

JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역
코드에서 사용되는 클래스 (.class)들을 클래스 로더로 읽어 클래스별로 정적 필드와 상수, 메소드 코드, 생성자 코드 등을 분류해서 저장한다.

힙 영역

객체와 배열이 생성되는 영역
여기에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다. 만일 참조하는 변수나 필드가 없다면 의미 없는 객체가 되기 때문에 JVM이 이것을 쓰레기로 취급하고 쓰레기 수집기를 실행시켜 제거한다. 따라서 개발자는 객체를 제거하기 위해 별도의 코드를 작성할 필요가 없다.
(사실 자바는 코드로 객체를 직접 제거하는 방법을 제공하지 않는다)

JVM 스택 영역

JVM 스택은 메소드를 호출할 때마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 동작을 수행한다.
프레임 내부에는 로컬 변수 스택이 있는데, 기본 타입 변수와 참조 타입 변수가 추가되거나 제거된다. 스택 영역에 변수가 생성되는 시점은 초기화가 될 때, 즉 최초로 변수에 값이 저장될 때이다.
변수는 선언된 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거된다.

기본 타입 변수는 스택 영역에 직접 값을 가지고 있지만, 참조 타입 변수는 스택 영역에 힙 영역의 객체 주소를 가진다. 다음과 같이 변수인 scores는 스택 영역에 생성되지만 실제 10,20,30을 갖는 배열은 힙 영역에 생성된다. 배열 변수 scores에는 배열의 힙 영역의 주소가 저장된다

참고로 자바에서는 배열을 객체로 취급한다.

null과 NullPointerException

참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻으로 null값을 가질 수 있다. null 값도 초기값으로 사용할 수 있기 때문에 null로 초기화된 참조 변수는 스택 영역에 생성된다.

자바는 프로그램 실행 도중에 발생하는 오류를 예외(Exception)라고 부른다. 예외는 사용자의 잘못된 입력으로 발생할 수도 있고, 프로그래머가 코드를 잘못 작성해서 발생할 수 있다.
참조 변수를 사용하면서 가장 많이 발생하는 예외 중 하나로 NullPointerException이 있다.
이 예외는 참조 타입 변수를 잘못 사용하면 발생한다.

int[] intArray = null;
intArray[0] = 10; // ←NullPointerException

String 타입

String 변수;
변수 = "문자열";

문자열은 String 객체로 생성되고 변수는 String 객체를 참조한다.

자바는 문자열 리터럴이 동일하다면 String 객체를 공유하도록 되어 있다. name1과 name2 변수가 동일한 문자열 리터럴인 "신용권"을 참조할 경우 name1과 name2는 동일한 String 객체를 참조하게 된다.

String name1 = "신용권";
String name2 = "신용권";

일반적으로 변수에 문자열을 저장할 경우 문자열 리터럴을 사용하지만, new 연산자를 사용해서 직접 String 객체를 생성시킬 수도 있다. new 연산자는 힙 영역에 새로운 객체를 만들 때 사용하는 연산자로 객체 생성 연산자라고 한다.

String name1 = new String("신용권");
String name2 = new String("신용권");

String 변수는 참조 타입이므로 초기값으로 null을 대입할 수 있는데, 이때 null은 String 변수가 참조하는 String 객체가 없다는 뜻이다.

참조를 잃은 String 객체는 JVM이 쓰레기 객체로 취급하고 쓰레기 수집기를 구동시켜 메모리에서 자동 제거한다.

String hobby = "여행";
hobby = null;

배열

배열을 사용하기 위해서는 우선 배열 변수를 선언해야 한다. 배열 변수 선언은 다음과 같이 두 가지 형식으로 작성할 수 있다.

타입[] 변수;
타입 변수[];

배열 변수도 참조 변수에 속한다. 배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 객체를 참조하게 된다. 만일 참조할 배열 객체가 없다면 배열 변수는 null 값으로 초기화될 수 있다.

값의 목록이 있다면 다음과 같이 간단하게 배열 객체를 생성할 수 있다.

타입[] 변수 = { 값0, 값1, 값2, 값3, ... };

예시 :

String[] names = { "신용권", "홍길동", "감자바" };

※ 배열 변수를 미리 선언한 후 값 목록들이 나중에 결정되는 상황이라면 다음과 같이 new 연산자를 사용해 값 목록을 지정해 준다.

변수 = new 타입[] { 값0, 값1, 값2, 값3, ... };

메소드의 매개값이 배열일 경우에도 마찬가지이다. 아래와 같이 매개 변수로 int[] 배열이 선언된 add()메소드가 있을 경우, 값 목록으로 배열을 생성함과 동시에 add() 메소드의 매개값으로 사용하고자 할 때는 반드시 new 연산자를 사용해야 한다.

int add(int[] scores) { ... }
int result add( {95, 85, 90} ); // 오류! 컴파일 에러
int result add( new int[] {95, 85, 90} ); // 정상

new 연산자로 배열 생성

타입[] 변수 = new 타입[길이]

new 연산자로 배열을 처음 생성할 경우 배열은 자동적으로 기본값으로 초기화된다.
학생 30명의 점수를 저장할 배열을 다음과 같이 생성한다고 가정해 보자.

int[] scores = new int[30]

String 배열의 경우 :

String[] names = new String[30];

명령 라인 입력

프로그램 실행을 위해 main() 메소드가 필요하다. 하지만 main() 메소드의 매개값인 String[] args가 왜 필요할까?

public static void main(String[] args) { ... }

명령 프롬프트에서 위 코드를 java 명령어로 실행하면 JVM은 길이가 0인 String 배열을 먼저 생성하고 main() 메소드를 호출할 때 매개값으로 전달한다.

예제 :

package sec03.exam01;

public class Hello {
	public static void main(String[] args) {
		if(args.length != 2) { // 입력한 데이터 개수가 2개가 아닐 경우
			System.out.println("값의 수가 부족합니다.");
			System.exit(0);
		}
		String strNum1 = args[0];
		String strNum2 = args[1];
		
		int num1 = Integer.parseInt(strNum1);
		int num2 = Integer.parseInt(strNum2);
		
		int result = num1+num2;
		System.out.println(num1 +" + "+num2+" = " + result);
	}
}

위의 예제를 실행하면 '값의 수가 부족합니다' 가 출력된다.
매개값을 주고 실행하면 다음과 같다.

다차원 배열

2행 3열 행렬을 만들기 위해 다음과 같은 코드를 사용한다.

int[][] scores = new int[2][3];

이 코드는 메모리에 다음과 같이 3개의 배열 객체를 생성한다.

향상된 for문

향상된 for문은 반복 실행을 하기 위해 루프 카운터 변수와 증감식을 사용하지 않는다. for문의 괄호에는 배열에서 꺼낸 항목을 저장할 변수 선언과 클론(:) 그리고 배열을 나란히 작성한다.

예제 :

package sec02.exam10;

public class AdvancedForExample {
    public static void main(String[] args) {
    	int[] scores = {95,71,84,93,87};
        int sum = 0;
        for (int score : scores) {
       	    sum = sum + score;
        }
        System.out.println("점수 총합 = " + sum);
        double avg = (double) sum/scores.length;
        System.out.println("점수 평균 = " + avg);
    }
}

열거 타입

열거 타입은 한정된 값인 열거 상수 중에서 하나의 상수를 저장하는 타입이다.
열거 타입을 선언하기 위해서는 먼저 열거 타입의 이름을 정하고 해당 이름으로 소스 파일(.java)을 생성해야 한다.
소스 파일의 내용으로는 다음과 같이 열거 타입 선언이 온다. public enum 키워드는 열거 타입을 선언하기 위한 키워드이며, 반드시 소문자로 작성한다.

public enum 열거타입이름 { ... }

열거 타입을 이클립스에서 생성하려면 [File] - [New] - [Enum] 을 선택하자

package sec03.exam01;

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

열거 타입을 선언했다면 이제 열거 타입을 사용할 수 있다.
열거 타입도 하나의 타입이므로 변수를 선언하고 사용해야 한다.

Week tooday = Week.SUNDAY;
Week birthday = null; // null값도 저장할 수 있다.

참조 타입 변수는 객체를 참조하는 변수다.
열거 상수는 객체일까? 그렇다.
열거 상수는 열거 객체로 생성된다. 열거 타입 변수 Week의 경우 7개의 Week 객체로 생성된다. 그리고 메소드 영역에 생성된 열거 상수가 해당 Week 객체를 각각 참조하게 된다.

Calendar 클래스

자바는 컴퓨터의 날짜 및 요일, 시간을 얻기 위해 Calendar 클래스를 제공한다.

//Calendar 클래스는 java.util 패키지에 있으므로 import가 필요
import java.util.Calendar;

//Calendar 변수를 선언하고 getInstance() 메소드로 Calendar 객체를 얻는다
Calendar cal = Calendar.getInstance

// Calendar 객체를 얻었다면 get() 메소드를 이용해서
// 일(1)~토(7)까지의 숫자를 int형 변수 week에 저장
int week = cal.get(Calendar_DAY_OF_WEEK);
profile
흔한 컴공러 / 3학년
post-custom-banner

0개의 댓글