본문 바로가기

코드스테이츠

[코드스테이츠 BE 45기] <Section1> Week2 (Java 기초)

Java 기초

<JAVA Intro>

1 자바의 특징

  • 운영체제에 독립적

JRE(Java Runtime Environment: JVM(자바 가상머신) + 표준 클래스 라이브러리)가 설치되어 있는 모든 운영체제에서 실행이 가능

  • 객체 지향 언어(Object Oriented Programming, OOP)

여러 부품(객체)들을 만들고 조립하여 하나의 프로그램을 실행

  • 함수형 프로그래밍 지원

컬렉션의 요소를 필터링, 매핑, 집계 처리하기 쉬워지고 코드가 간결해짐

(함수형 프로그래밍을 지원하는 문법인 람다식과 스트림)

  • 자동 메모리 관리(Garbage Collection)

2 JVM과 JDK

  • JVM(Java Virtual Machine)= 자바 프로그램을 실행시키는 도구
  • : 자바 코드로 작성한 프로그램을 해석해 실행하는 별도의 프로그램
  • JDK(Java Development Kit)

JRE(Java Runtime Environment) : JVM + 표준 클래스 라이브러리

"Runtime", 즉 실행과 관련된 무언가입니다.

JDK(Java Development Kit) : JRE + 개발에 필요한 도구

"Development", 즉 개발과 관련된 무언가입니다.

3 메서드

public class Main {
  public static void main(String[] args) {

  }
}
  • public class Main { … }
    “Main이라는 이름의 클래스가 있고, 그 안에서 코드를 작성할 수 있구나!”
    
  • : 접근 허용 범위가 public인 Main이라는 이름의 클래스를 정의하겠다.
  • public static void main(String[] args) { … }

public static은 나중에 배울 클래스와 관련된 개념이니 소거

void main(String[] args) { … }

좀 더 간단하게 표현

A main(B C) { D }

A main(B C) { D }는 메서드를 정의하는 문법

메서드란, 어떤 기능을 하는 코드를 묶음으로 묶은 것을 의미

            어떠한 기능을 수행하기 위한 일련의 코드들의 집합체

어떤 기능을 수행한다 = 데이터를 입력받아 해당 데이터에 일련의 처리를 가함으로써 만들어낸 결과값을 반환하는 것을 의미

반환한다 = 메서드 내부의 코드가 만들어낸 결과값을 내보내는 것

1 메서드 정의

A main(B C) {  //반환_타입 메서드_이름(매개변수_타입 매개변수_이름) {
	D            //메서드_바디
}              //}

메서드란, ‘어떤 기능을 수행하기 위한 코드들을 묶어놓은 것’이며, 여기에서 ‘어떤 기능을 수행한다’는 것은 데이터를 입력받아 입력받은 데이터에 일련의 처리를 가한 후, 그 결과값을 반환하는 것을 의미

  • A는 반환 타입을 의미
                       메서드를 정의할 때 메서드 이름 앞에 반환 타입을 명시해 주어야 함.
    
    • 값에는 종류가 나뉘어 있음
  • 예)정수를 나타내는 정수형, 한 개의 문자를 나타내는 문자형 등
  • • 반환 타입: 메서드가 반환할 반환 값의 종류 및 유형을 의미.
  • B = 매개변수의 타입, C = 매개변수의 이름• 매개변수의 이름: 입력받은 값에 어떤 이름을 붙여 사용할 것인지를 명시하는 것을 의미
                       메서드 외부와 메서드 내부를 매개해 주는 변수라는 의미에서 매개변수라고 부름
    
    • 메서드는 메서드 외부에서 메서드 내부로 전달된 값, 어떤 데이터를 입력받는데 이 값은 ‘변수’라는 것에 저장할 수 있음• 메서드를 정의할 때는 메서드 이름 옆에 소괄호를 열고, 그 안에 매개변수의 타입과 매개변수의 이름을 공백으로 구분하여 명시해야 함
  • • 할당한다 = 변수에 어떤 값을 저장한다 • 매개변수 : 외부로부터 전달 받은 값을 저장하고 있는 변수
  • • 매개변수: 메서드 외부에서 메서드 내부로 전달한 값을 할당받아 저장함으로써, 메서드 내부에서 사용할 수 있게 해 줌
  • • 매개변수의 타입: 어떤 유형의 값을 메서드가 입력받을 것인지를 명시하는 것을 의미
  • D = 메서드 바디• return키워드를 사용해 어떤 값을 반환할 수 있음(메서드의 처리 결과값을 외부로 내보낼 수 있음)
  • • 구체적으로 메서드가 어떤 기능을 수행할지에 대한 코드를 작성하는 부분
int add(int number1, int number2) {
	return number1 + number2;
}

<더하기를 수행하는 기능을 가진 메서드>

  1. 정수형 값 2개를 입력받음
  2. 입력받은 값 2개는 매개변수 number1과 number2에 각각 할당됨
  3. 메서드 몸체에서는 return 키워드를 통해 number1과 number2에 저장된 값을 더한 값을 결과값으로 반환함

2 메서드 호출

add(1, 2);
 •  메서드 이름에 호출 연산자 `()`를 붙여서 메서드를 호출할 수 있음

   `()` 안에는 매개변수에 넣어줄 값을 입력

 •  `add(1, 2);`와 같이 1과 2를 전달하면서 `add()` 메서드를 호출하면 `add()` 메서드 내에서 `number1`에는 1이, `number2`에는 2가 저장되며, `return number1 + number2`라는 코드가 실행됨에 따라 3이 리턴됨
int result = add(1,  2);
System.out.println(result);

<add() 메서드의 결과값을 출력하는 코드>

  • int result = add(1, 2);
    • 1과 2를 입력값으로 전달하면서 앞서 정의한 add() 메서드를 실행시키고, 그 결과값을 result라는 변수에 저장
  • System.out.println(result);
    • result에 저장된 값을 콘솔에 출력시키는 코드

3 main 메서드

public static void main(String[] args) {

}
  • void : “정확히 무엇인지는 모르겠지만, 반환 타입을 의미하는구나!”
  • main : “메서드의 이름이 main이구나!”• 자바에서 main 메서드는 진입점 함수이며, 자바로 어떤 소스 코드를 작성할 때 반드시 main 메서드가 있어야 하고, main 메서드로부터 코드의 흐름이 시작함
  • • main 메서드는 자바로 작성한 소스 코드 파일을 실행하면 가장 먼저 실행되는 메서드 (진입점 함수: 프로그램이 실행될 때 가장 먼저 실행되는 메서드 또는 함수)
  • String[] : “정확히 무엇인지는 모르겠지만 매개변수의 타입이 String[] 타입이구나!”
  • args : “입력 데이터로 들어오는 값을 args라는 이름의 매개변수에 할당하는구나!”
  • “그리고 중괄호 블록 {} 안에 코드를 작성하면 되는구나!”

<변수와 타입>

1기억하고자 하는 값이 얼만큼의 메모리 공간을 필요로 하는지 파악합니다.

2기억하고자 하는 값이 차지하는 용량만큼의 메모리 공간을 확보합니다.

3값을 저장한 공간에 이름을 붙입니다.

4확보한 메모리 공간에 기억하고자 하는 값을 저장합니다.

1~3 : 변수를 선언한다

4: 변수에 값을 할당한다

1. 변수

: 값을 저장할 수 있는 메모리 공간을 확보하고, 사람이 식별할 수 있는 이름을 붙인 것

  • 변수의 선언과 할당
  1. 변수 선언
  2. : 변수를 선언한다는 것은 어떤 값을 저장할 메모리 공간을 확보하고, 해당 메모리 공간을 식별할 수 있는 이름을 붙이는 것을 의미
class Main {
	public static void main(String[] args) {
		int num; // 변수 선언
	}
}

• num이라는 변수에 정수형의 숫자를 저장

= 변수 num은 int형이다. → int형은 4byte다. → 따라서 4byte의 메모리 공간을 확보해야 한다.

• int num; = “컴퓨터야, int형 값을 저장할 거니까 int형의 데이터 크기인 4byte만큼의 메모리 공간을 확보해 줘. 그리고 그 공간에 num이라고 이름을 붙여줘.“

  1. 값 할당
    대입 연산자 ‘=’ 사용. `좌항 = 우항;`과 같은 형식으로 사용. 우항에는 값이, 좌항에는 변수가 위치해야 함.
    
  2. : 변수에 값을 저장하는 것
class Main {
	public static void main(String[] args) {
		int num; // 변수 선언
		num = 1; // 값 할당(초기화)
		num = 2; // 값 할당(재할당)
	}
}

• num을 1로 초기화한 후, 2로 재할당하면 num에 저장되어 있던 1은 사라지고 2가 저장됨

• 초기화: 변수를 선언하고 나서 처음으로 값을 할당하는 것

• 재할당: 초기화가 이루어진 후에 다시 다른 값을 할당하는 것

class Main {
	public static void main(String[] args) {
		int num = 1; // 선언과 동시에 초기화
	}
}

• 변수를 선언하면서 동시에 초기화도 가능

  1. 변수 명명 규칙
  2. : 변수 이름을 지을 때 지켜야 하는 룰
1 int camelCase;
2 // 아래의 모든 변수의 변수명은 허용되는 변수명입니다. 
  int num;
  int NUM; // num과 다른 변수입니다. 
  int num_1;
  int num$1;
3 int 10Age; // Error
4 int byte;  // Error
  int class; // Error
  • 카멜 케이스(camelCase): 두 번째 단어부터 대문자로 시작해 구분
  • 변수명으로 영문자, 숫자, _, $를 사용할 수 있으며, 영문자는 대소문자가 구별되어 인식됩니다. 즉, a와 A는 다른 문자로 인식됨
  • 숫자로 시작하는 변수명은 사용할 수 없음
  • 자바에서 이미 사용 중인 예약어(reserved word)는 변수명으로 사용할 수 없음

2**. 상수**

: 변하지 말아야 할 데이터를 임시로 저장하기 위한 수단

재할당이 금지된 변수

final이라는 키워드를 사용해 선언할 수 있으며, 관례로 대문자에 언더바(_)를 넣어 구분하는 SCREAMING_SNAKE_CASE를 사용

final double CALCULATOR_PI  = 3.14;
  • 상수를 사용하는 이유• 코드 가독성을 높이고 싶은 경우
  • • 코드 유지관리를 손쉽게 하고자 하는 경우
  • • 프로그램이 실행되면서 값이 변하면 안 되는 경우

3**. 타입**

: 타입에 따라 값이 차지하는 메모리 공간의 크기와, 값이 저장되는 방식이 결정됨

  1. 기본 타입: 값을 저장할 때, 데이터의 실제 값이 저장됨
  2. • 정수 타입(byte, short, int, long), 실수 타입(float, double), 문자 타입(char), 논리 타입(boolean)
  3. 참조 타입: 값을 저장할 때, 데이터가 저장된 곳을 나타내는 주소값이 저장됨
  4. • 객체의 주소를 저장, 8개의 기본형을 제외한 나머지 타입
public class Main {
    public static void main(String[] args) {
        int primitive = 1;  //기본타입변수 = 1;
        Object reference = new Object();  //참조타입변수 = 객체;

        System.out.println(primitive);  //출력(기본타입변수);
        System.out.println(reference);  //출력(참조타입변수);
    }
}

4**. 리터럴**

: 문자가 가리키는 값 그 자체를 의미

class Main {
	public static void main(String[] args) {
		int num; // 변수 선언
		num = 1; // 값 할당
	}
}

num에 할당하고 있는 1이 리터럴

  • 리터럴을 사용할 때 알아두어야 하는 사항

1 float 타입의 변수에 실수형 리터럴을 할당할 때, 리터럴 뒤에 접미사 f를 붙여주어야 함

2 long 타입의 변수에 정수형 리터럴을 할당할 때, 리터럴 뒤에 접미사 L을 붙여주어야 함

float weight = 74.5f;
final long LIGHT_YEAR = 9460730472580L;

float = 9460730472580.0F;
double = 9460730472580.0D;

5**. 정수타입**

: 숫자를 나타내는 타입으로, byte(1byte), short(2byte), int(4byte), long(8byte)의 총 4개의 타입으로 분류

정수형을 사용할 때는 일반적으로 int형을 사용

1 정수형의 오버플로우와 언더플로우

  • 오버플로우

• 최대값을 넘어가면 해당 데이터 타입의 최소값으로 값이 순환

예 : 어떤 값이 byte형이고, byte형의 최대값인 127을 값으로 가지는 경우, 이 값에 1을 더하면 128이 되는 게 아니라, 최소값인 -128이 됨

  • 언더플로우

• 최소값을 넘어가면 해당 데이터 타입의 최대값으로 값이 순환

예 : 어떤 값이 byte형이고, byte 형의 최소값인 -128을 값으로 가지는 경우, 이 값에 1을 빼면 -129가 되는 게 아니라, 최대값인 127이 됩니다.

2 데이터 타입의 크기와 표현 범위

: 데이터 타입의 크기가 데이터의 표현 범위를 결정 ****byte → short → int → long

6**. 실수타입**

: 소수점을 가지는 값을 의미하며, float(4byte형)과 double(8byte형)으로 분류

1 double형 리터럴에는 접미사 d를 붙여도, 붙이지 않아도 됨

2 float형 리터럴에는 반드시 접미사 f를 붙여주어야 함

  • double형은 float형보다

1 더 큰 실수를 저장할 수 있고 2 더 정확하게 저장할 수 있음

  • 실수형에서도 오버플로우와 언더플로우가 발생하지만, 오버플로우와 언더플로우가 발생했을 때의 결과가 다름• 언더플로우: 값이 음의 최대 범위 또는 양의 최소 범위를 넘어갔을 때 발생. 이때 값은 0
  • • 오버플로우: 값이 음의 최소 범위 또는 양의 최대 범위를 넘어갔을 때 발생. 이때 값은 무한대

7**. 논리타입**

 : `boolean`형은 참 또는 거짓을 저장할 수 있는 데이터 타입으로, 오직 `true` 혹은 `false`를 값으로 가짐

   `boolean`형은 조건문과 함께 사용되는 경우가 많음
boolean isRainy = true;
boolean isAdult = false;

8**. 문자타입**

 : `char`형

  문자 타입 변수를 선언하면 해당 변수에 오직 하나의 문자형 리터럴을 저장할 수 있음

  문자형 리터럴을 작성할 때는 반드시 큰따옴표(`””`)가 아닌 작은따옴표(`’’`)를 사용하여야 함
char letter1 = 'a';
char letter2 = 'ab'; // 에러 : 단 하나의 문자만 할당할 수 있습니다. 
char letter3 = "a"   // 에러 : 작은따옴표를 사용해야 합니다.

숫자를 문자형 변수에 할당하면 해당 숫자가 그대로 저장되지만, 나중에 변수를 참조할 때, 즉 변수의 값을 읽어올 때 해당 변수가 저장하고 있는 숫자값을 유니코드로 인식하여 해당 숫자와 일치하는 코드를 가진 문자로 변환해줌

char letter = 65;
System.out.print(letter); // 출력 결과 : A

9**. 타입 변환**

1 자동 타입 변환

  • 바이트 크기가 작은 타입에서 큰 타입으로 변환할 때 (예 : byte → int)
  • 덜 정밀한 타입에서 더 정밀한 타입으로 변환할 때 (예 : 정수 → 실수)
byte(1) -> short(2)/char(2) -> int(4) -> long(8) -> float(4) -> double(8)
//float은 4byte인데 int와 long보다 더 뒤쪽에 있음
//이는 float이 표현할 수 있는 값이 모든 정수형보다 더 정밀하기 때문

// float이 long보다 정밀하므로, 자동으로 타입이 변환됩니다.
long  longValue  = 12345L;
float floatValue = longValue;

System.out.println(floatValue); // 12345.0이 출력됩니다.

<화살표를 기준으로 좌측의 타입이 우측의 타입으로 자동으로 변환될 수 있음>

2 수동 타입 변환

: 수동으로 타입을 변환할 때는 캐스팅 연산자 ()를 사용하며, 캐스팅 연산자의 괄호 안에 변환하고자 하는 타입을 작성

//int 타입으로 선언된 변수 intValue를 더 작은 단위인 byte로 변환합니다.
int intValue = 128;
byte byteValue = (byte)intValue;

System.out.println(byteValue); // -128

<문자열(String)>

  1. String 타입의 변수 선언과 할당

String 타입은 큰따옴표("")로 감싸진 문자열을 의미

// 문자열 리터럴을 String 타입의 변수 name에 할당하는 방법
String name1 = "Kim Coding";

// String 클래스의 인스턴스를 생성하는 방법
String name2 = new String("Kim Coding");

System.out.print(name1); // "Kim Coding"
System.out.print(name2); // "Kim Coding"

<String 타입의 변수를 선언하고, 문자열 리터럴을 할당하는 방법>

  • String 타입의 변수는 String 변수명;으로 선언할 수 있다.
  • 선언한 변수에 문자열을 할당하는 방법은 두 가지가 있다.2 String 클래스의 인스턴스를 생성하여 할당하는 방법 : 변수 = new String(”문자열”);
  • 1 문자열 리터럴을 할당하는 방법 : 변수 = “문자열”;
1  String name1 = "Kim Coding";
2  String name2 = "Kim Coding";
3
4  String name3 = new String("Kim Coding");
5  String name4 = new String("Kim Coding");
6
7  boolean comparison1 = name1 == "Kim Coding";      // true
8  boolean comparison2 = name1 == name2;             // true
9  boolean comparison3 = name1 == name3;             // false
10  boolean comparison4 = name3 == name4;             // false
11  boolean comparison5 = name1.equals("Kim Coding"); // true
12  boolean comparison6 = name1.equals(name3);        // true
13  boolean comparison7 = name3.equals(name4);        // true
  • 등가 비교 연산자 == : 좌항 == 우항의 형태로 사용할 수 있으며, 좌항의 값과 우항의 값이 일치하는지 검사하여 일치하면 true를, 일치하지 않으면 false를 반환
  • equals() 메서드 : .앞의 변수가 저장하고 있는 문자열의 내용과 () 안의 문자열의 내용이 같은지 비교하여 같으면 true를 다르면 false를 반환• equalsIgnoreCase() 메서드는 대소문자를 구분하지 않고 비교
  • • equals() 메서드는 내용이 같은지 만을 비교
  • 1~2 : 문자열 리터럴을 할당하는 방법 : 변수 = “문자열”; 사용• name1과 name2가 저장하게 되는 문자열의 주소값은 같음
  • • 동일한 문자열 리터럴을 두 변수에 할당하는 경우, 두 변수는 같은 문자열의 참조값을 공유
  • 4~5 : String 클래스의 인스턴스를 생성하여 할당하는 방법 : 변수 = new String(”문자열”); 사용• name3과 name4는 서로 다른 인스턴스의 주소값을 저장
  • • String 클래스의 인스턴스를 생성하게 되면 문자열의 내용이 같을지라도, 별개의 인스턴스가 따로 생성 (String 클래스로 인스턴스를 생성하면 항상 별개의 인스턴스가 생성되므로 두 변수는 서로 다른 주소값을 저장하게 됨)
  1. String 클래스의 메서드

1 charAt() 메서드

: 해당 문자열의 특정 인덱스에 해당하는 문자를 반환

해당 문자열의 길이보다 큰 인덱스나 음수를 전달하면, 오류가 발생
String str = new String("Java");
System.out.println("문자열 : " + str); // "문자열 : Java"

System.out.println(str.charAt(0)); // 'J'
System.out.println(str.charAt(1)); // 'a'
System.out.println(str.charAt(2)); // 'v'
System.out.println(str.charAt(3)); // 'a'

System.out.println("\\ncharAt() 메서드 호출 후 문자열 : " + str);

<문자열의 각 문자를 charAt() 메서드를 이용하여 하나씩 출력>

2 compareTo() 메서드

: 해당 문자열을 인수로 전달된 문자열과 사전 편찬 순으로 비교 (문자열을 비교할 때 대소문자를 구분하여 비교)

두 문자열이 같다면 0을 반환하며, 해당 문자열이 인수로 전달된 문자열보다 작으면 음수를, 크면 양수를 반환

문자열을 비교할 때 대소문자를 구분하지 않기를 원한다면, `compareToIgnoreCase()` 메서드 사용
String str = new String("abcd");
System.out.println("문자열 : " + str);
System.out.println(str.compareTo("bcef"));
System.out.println(str.compareTo("abcd") + "\\n");
System.out.println(str.compareTo("Abcd"));
System.out.println(str.compareToIgnoreCase("Abcd"));
System.out.println("compareTo() 메서드 호출 후 문자열 : " + str);

<compareTo() 메서드와 compareToIgnoreCase() 메서드를 이용하여 두 문자열을 비교>

3 concat() 메서드

: 해당 문자열의 뒤에 인수로 전달된 문자열을 추가한 새로운 문자열을 반환

인수로 전달된 문자열의 길이가 0이면, 해당 문자열을 그대로 반환
String str = new String("Java");
System.out.println("문자열 : " + str);
System.out.println(str.concat("수업"));
System.out.println("concat() 메서드 호출 후 문자열 : " + str);

<concat() 메서드를 이용하여 두 문자열을 연결>

4 indexOf() 메서드

해당 문자열에서 특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환

해당 문자열에 전달된 문자나 문자열이 포함되어 있지 않으면 -1을 반환

String str = new String("Oracle Java");
System.out.println("문자열 : " + str);
System.out.println(str.indexOf('o'));
System.out.println(str.indexOf('a'));
System.out.println(str.indexOf("Java"));
System.out.println("indexOf() 메서드 호출 후 원본 문자열 : " + str);

<indexOf() 메서드를 이용하여 특정 문자나 문자열이 처음 등장하는 위치의 인덱스를 찾기>

5 trim() 메서드

: 해당 문자열의 맨 앞과 맨 뒤에 포함된 모든 공백 문자를 제거

String str = new String(" Java     ");
System.out.println("문자열 : " + str);
System.out.println(str + '|');
System.out.println(str.trim() + '|');
System.out.println("trim() 메서드 호출 후 문자열 : " + str);

<trim() 메서드를 이용하여 문자열에 포함된 띄어쓰기와 탭 문자를 제거>

6 toLowerCase()와 toUpperCase() 메서드

: toLowerCase() 메서드는 해당 문자열의 모든 문자를 소문자로 변환시켜 줌

`toUpperCase()` 메서드는 해당 문자열의 모든 문자를 대문자로 변환
String str = new String("Java");
System.out.println("문자열 : " + str);
System.out.println(str.toLowerCase());
System.out.println(str.toUpperCase());
System.out.println("두 메서드 호출 후 문자열 : " + str);

<toLowerCase() 메서드와 toUpperCase() 메서드를 이용하여 문자열의 대소문자를 변경>