멀티캠퍼스

[2026.04.14]TIL - 12일차 Java 변수와 메모리 구조, 메소드, 연산자 정리

buckwheat 2026. 4. 14. 17:38

이번에는 자바에서 배운 내용을 Variable, Method, Operator 순서로 정리했다.

변수에서는 형 변환, 메모리 구조, 출력 메소드, escape 문자, Scanner를 정리하고, 메소드에서는 접근제한자와 static 메소드, 메소드 실행 방식을 정리했다. 마지막으로 연산자에서는 자주 사용하는 연산자 종류와 삼항연산자, 복합대입 연산자를 정리했다.

 

1. Variable

1) 형 변환(casting)

자바에서는 자료형이 서로 다르면 값을 그대로 대입하거나 계산할 수 없는 경우가 있다. 이때 필요한 것이 형 변환이다. 형 변환은 자료형을 다른 형태로 바꾸는 과정이다.

 

형 변환에는 자동 형변환 강제 형변환이 있다.

  • 자동 형변환

크기가 작은 자료형이 큰 자료형으로 바뀔 때 자바가 자동으로 처리하는 방식이다.

예를 들어 intdouble을 함께 계산하면 int 값이 double로 바뀐 뒤 연산이 진행된다. 그래서 결과도 실수형으로 나온다.

 

  • 강제 형변환

개발자가 직접 자료형을 바꾸겠다고 표시하는 방식이다. 보통 큰 자료형을 작은 자료형으로 바꿀 때 사용한다.

예를 들어 double 값을 int로 바꾸면 소수점 아래 값이 사라진다.

이처럼 강제 형변환은 값 손실이 생길 수 있기 때문에 주의해서 사용해야 한다.

 

또한 byteshort는 계산 결과가 int로 처리된다는 점도 중요하다. 그래서 byte + byte의 결과를 다시 byte에 저장하려면 강제 형변환이 필요할 수 있다.

 

형 변환은 자료형이 다를 때 값을 맞추는 과정이다.
안전한 방향은 자동 형변환, 값 손실 가능성이 있는 방향은 강제 형변환으로 처리된다고 이해하면 된다.

 

2) 변수와 메모리 구조

변수는 값을 저장하는 공간이다. 프로그램에서 숫자, 문자, 문자열 같은 데이터를 사용하려면 그 값을 어딘가에 저장해야 하는데, 그 역할을 하는 것이 변수이다.

 

그런데 변수는 단순히 이름만 있는 것이 아니라 실제 메모리 공간과 연결되어 있다. 자바에서는 메모리 구조를 크게 Static 영역, Heap 영역, Stack 영역으로 나누어 이해할 수 있다.

Static 영역

 static 예약어가 붙은 필드나 메소드가 저장되는 공간이다. 프로그램이 시작될 때 생성되고, 프로그램이 끝날 때까지 유지된다.

클래스 전체에서 공통으로 사용하는 값이나 기능이 여기에 해당한다.

 

Heap 영역

 new 연산자를 사용해서 만든 객체나 배열이 저장되는 공간이다.

예를 들어 객체를 생성하면 실제 데이터는 Heap 영역에 만들어진다. 쉽게 말하면 새로 만든 객체가 들어가는 공간이다.

 

Stack 영역

메소드가 실행될 때 필요한 지역변수, 매개변수, 메소드 호출 정보 등이 저장된다.

메소드가 호출되면 Stack에 필요한 값이 생기고, 메소드가 끝나면 자동으로 사라진다.

그래서 지역변수는 해당 메소드 안에서만 사용할 수 있다.

 

정리하면

  • Static : 프로그램 전체에서 공통으로 쓰는 공간
  • Heap : new로 만든 객체나 배열이 저장되는 공간
  • Stack : 메소드 실행 중 잠깐 사용하는 지역변수와 호출 정보가 저장되는 공간

이 구조를 이해하면 왜 지역변수는 메소드가 끝나면 사라지는지, 왜 객체는 new를 사용해서 만들어야 하는지, 왜 static은 객체 없이도 사용할 수 있는지 이해하기 쉬워진다.

 

3) 출력 메소드

 

자바에서 출력은 값을 화면에 보여주는 기능이다. 대표적인 출력 메소드는 print(), println(), printf()이다.

print() 값을 출력만 하고 줄바꿈은 하지 않는다.
println() 값을 출력한 뒤 줄바꿈까지 함께 한다.
printf() 형식에 맞춰 출력할 때 사용한다.

 

단순히 값을 한 줄씩 보고 싶다면 println()이 가장 편하다. 반대로 줄을 이어서 출력하고 싶다면 print()를 사용하면 된다.

숫자나 문자열을 일정한 형식으로 맞춰서 깔끔하게 출력하고 싶다면 printf()를 사용한다.

 

출력 메소드는 모두 값을 보여주는 역할을 하지만, 결과를 화면에 어떻게 보이게 할지에 따라 사용하는 방식이 달라진다.

 

4) escape 문자

escape 문자는 문자열 안에서 특별한 기능을 하는 문자이다. 자바에서는 역슬래시 \와 함께 사용한다.

 

대표적인 escape 문자는 다음과 같다.

  • \n : 줄바꿈
  • \t : 탭 간격
  • \" : 큰따옴표 출력
  • \\ : 역슬래시 출력

 

문자열 안에서 줄을 바꾸고 싶으면 \n을 사용하고, 문자열 안에 큰따옴표 자체를 넣고 싶으면 \"를 사용해야 한다.

escape 문자는 문자열 안에서 단순한 글자 이상의 특별한 동작을 하게 만드는 기능이라고 볼 수 있다.

 

5) Scanner

Scanner는 자바에서 사용자 입력을 받을 때 사용하는 클래스이다. 사용자가 키보드로 입력한 값을 프로그램 안으로 가져오는 역할을 한다.

 

정수는 nextInt(), 실수는 nextDouble(), 문자열은 next()nextLine()으로 입력받을 수 있다.

 

여기서 중요한 차이는 next()nextLine()이다.

next()는 공백 전까지만 읽는다. 따라서 단어 하나를 입력받을 때 적합하다.

반면 nextLine()은 한 줄 전체를 읽기 때문에 띄어쓰기가 있는 문장도 한 번에 입력받을 수 있다.

 

Scanner는 프로그램이 사용자와 값을 주고받을 수 있도록 해주는 도구이며,
입력받는 데이터 형태에 따라 메소드를 다르게 선택해야 한다.

 


2. Method

 

1) 메소드

 

메소드는 특정 기능을 하나로 묶어놓은 단위이다.

프로그램에서 모든 코드를 main()에만 작성하면 길고 복잡해지기 때문에, 기능별로 나누어서 메소드로 작성한다.

 

예를 들어 출력만 담당하는 메소드, 계산을 담당하는 메소드, 값을 비교하는 메소드처럼 역할에 따라 구분할 수 있다. 이렇게 하면 코드가 더 정리되고, 같은 기능을 여러 번 사용할 때도 편리하다.

 

즉, 메소드는 프로그램을 기능 단위로 나누어 관리하기 위한 구조라고 볼 수 있다.

 

2)메소드 실행 방식

 

자바에서 메소드를 실행할 때 아래와 같은 형태를 자주 사용한다.

 

//1. 준비

//클래스명 변수명 = new 클래스명();

 

//2. 실행

//변수명.메소드명();

 

클래스 자료형으로 변수를 만들고 new를 사용해서 객체를 생성한 뒤,

그 객체를 통해 메소드를 호출하는 방식이다.

 

예를 들어 먼저 객체를 준비하고, 그다음 실행하는 형태가 있다.

이 방식은 일반 메소드를 사용할 때 필요하다.

 

왜냐하면 일반 메소드는 클래스 자체에 붙어 있는 것이 아니라 객체에 속한 기능이기 때문이다.

즉, 메소드를 실행하려면 먼저 그 클래스로 객체를 하나 만들어야 한다.

그래서 순서가 보통 이렇게 된다.

 

  1. 객체 생성
  2. 객체를 통해 메소드 호출

예를 들어 Variable05 test = new Variable05();처럼 객체를 만들면,

test라는 참조변수는 생성된 객체를 가리키게 된다.

그다음 test.메소드명()처럼 작성해서 그 객체의 메소드를 실행하는 것이다.

 

이 방식은 객체를 여러 번 사용할 때 편하다.

한 번 객체를 만들어두면 그 객체로 여러 메소드를 계속 호출할 수 있기 때문이다.

 

반대로 객체를 한 번만 잠깐 사용할 때는 객체 생성과 실행을 한 줄로 합쳐서 쓰기도 한다.

예를 들어 new Operator04().test02(); 같은 형태이다.

 

이 방식은 다음 의미를 가진다.

 

  • new Operator04() : Operator04 객체를 즉시 생성
  • .test02() : 방금 생성한 객체로 test02() 메소드 실행

즉, 객체를 따로 변수에 저장하지 않고 바로 사용한 것이다. 한 번만 실행하고 끝날 때는 이 방식이 더 간단하다.

  • 객체를 여러 번 사용할 때 : 변수에 저장해서 실행
  • 객체를 한 번만 사용할 때 : new 클래스명().메소드명() 형태로 바로 실행

결국 이런 방식을 쓰는 이유는, 일반 메소드가 객체에 속해 있기 때문이다.

객체가 있어야 일반 메소드를 사용할 수 있으므로 new를 통해 객체를 만들고, 그 객체로 메소드를 호출하는 것이다.

 

3) 접근제한자에 따른 메소드 종류

메소드에는 접근제한자를 붙일 수 있다. 접근제한자는 해당 메소드를 어디까지 사용할 수 있는지 정하는 역할을 한다.

 

public

public 메소드는 어디서나 접근할 수 있다. 같은 클래스, 다른 클래스, 다른 패키지 어디서든 사용할 수 있다.

 

private

private 메소드는 현재 클래스 안에서만 사용할 수 있다. 다른 클래스에서는 객체를 만들더라도 호출할 수 없다.

 

즉, 외부에서 사용할 수 없고 현재 클래스 내부 전용 메소드라고 볼 수 있다.

 

default

접근제한자를 따로 쓰지 않으면 default가 된다. default 메소드는 같은 패키지 안에서만 접근할 수 있다.

 

즉, 같은 패키지에 있는 클래스끼리는 사용할 수 있지만, 다른 패키지에서는 사용할 수 없다.

 

protected

protected 메소드는 같은 패키지 안에서 접근할 수 있고, 패키지가 달라도 상속 관계라면 접근할 수 있다.

 

즉, default보다 범위가 조금 더 넓다. 같은 패키지에서는 사용 가능하고, 다른 패키지라도 상속받은 자식 클래스에서는 사용할 수 있다.

 

4) protected와 상속

protected의 특징은 상속 관계에서 더 분명하게 보인다.

 

어떤 클래스가 MethodTest01을 상속받고 있다면, 자식 클래스에서는 부모 클래스의 protected 메소드를 사용할 수 있다. 이때 super.protectedMethod()처럼 부모의 메소드를 직접 호출할 수 있다.

 

여기서 super는 부모 클래스를 가리키는 키워드이다.

즉, 상속받은 자식 클래스에서는 부모의 public 메소드뿐 아니라 protected 메소드도 접근할 수 있다.

 

반면 private 메소드는 상속받더라도 직접 접근할 수 없다.

왜냐하면 private는 해당 클래스 내부에서만 허용되기 때문이다.

 

즉, protected는 상속 관계까지 고려한 접근제한자라고 정리할 수 있다.

 

5) 다른 패키지에서의 접근

다른 패키지에서 MethodTest01 객체를 생성하면 접근 가능한 범위가 달라진다.

 

이 경우 public 메소드는 사용할 수 있다.

하지만 default 메소드는 같은 패키지 안에서만 허용되므로 사용할 수 없다.

protected 메소드도 단순히 객체를 만들었다고 해서 바로 사용할 수는 없다. protected는 다른 패키지에서는 상속 관계일 때만 접근 가능하기 때문이다.

 

그래서 다른 패키지에서 객체를 생성한 경우에는 보통 publicMethod()는 호출할 수 있지만, protectedMethod()defaultMethod()는 바로 호출할 수 없다.

 

즉, 접근제한자는 메소드의 사용 범위를 정해주는 기준이며, 패키지와 상속 여부에 따라 접근 가능 여부가 달라진다.

 

6) static 메소드

static 메소드는 일반 메소드와 다르게 객체를 만들지 않아도 사용할 수 있다.

클래스에 속한 메소드이기 때문에 클래스명.메소드명() 형태로 호출한다.

 

예를 들어 MethodTest01.staticMethod()처럼 사용할 수 있다. 이때는 new MethodTest01()로 객체를 만들 필요가 없다.

 

반면 일반 메소드는 객체에 속한 기능이기 때문에 반드시 객체를 먼저 생성한 뒤 호출해야 한다.

즉, 일반 메소드는 객체명.메소드명() 형태이고, static 메소드는 클래스명.메소드명() 형태이다.

 

이 차이는 메소드가 어디에 속하는지로 이해하면 쉽다.

 

  • 일반 메소드 : 객체에 속한 기능
  • static 메소드 : 클래스에 속한 공통 기능

 

그래서 static 메소드는 특정 객체 하나를 위한 기능이라기보다, 클래스 전체에서 공통으로 사용하는 기능을 만들 때 사용한다.

 


3. Operator

연산자

 

연산자는 값을 계산하거나 비교하거나 조건을 판단할 때 사용하는 기호이다. 자바에서는 다양한 종류의 연산자를 사용하며, 프로그램의 흐름을 만드는 데 중요한 역할을 한다.

 

1) 산술 연산자

산술 연산자는 기본적인 계산에 사용되는 연산자이다.

+, -, *, /, %가 있다.

  • + : 덧셈
  • - : 뺄셈
  • * : 곱셈
  • / : 나눗셈
  • % : 나머지

특히 %는 나머지를 구하는 연산자이기 때문에 짝수와 홀수를 판별할 때 자주 사용된다.

2) 비교 연산자

비교 연산자는 두 값을 비교해서 결과를 참 또는 거짓으로 반환한다.

  • == : 같다
  • != : 다르다
  • > : 크다
  • < : 작다
  • >= : 크거나 같다
  • <= : 작거나 같다

비교 연산자는 조건문에서 매우 자주 사용된다. 값의 크기나 일치 여부를 판단할 때 필요한 연산자이다.

 

3) 논리 연산자

논리 연산자는 여러 조건을 함께 판단할 때 사용한다.

  • && : 두 조건이 모두 참일 때 참
  • || : 둘 중 하나만 참이어도 참
  • ! : 참과 거짓을 반대로 바꿈

예를 들어 어떤 수가 1 이상이면서 10 이하인지 확인하려면 두 조건을 &&로 연결할 수 있다.

즉, 논리 연산자는 조건을 조합하는 역할을 한다.

 

4) 삼항연산자

 

삼항연산자는 조건에 따라 두 값 중 하나를 선택하는 연산자이다.

형식은 다음과 같다.

 

조건식 ? 참일 때 값 : 거짓일 때 값

 

이 연산자는 간단한 조건문을 한 줄로 표현할 때 유용하다.

예를 들어 어떤 수가 양수인지 아닌지를 바로 문자열로 표현할 수 있다.

 

또 삼항연산자는 중첩해서 사용할 수도 있다.

예를 들어 수가 0보다 크면 양수, 0이면 0, 그 외에는 음수처럼 여러 갈래로 나누어 표현할 수도 있다.

String res = (num > 0)? "양수다" : (num==0)? "0이다" : "음수다";

 

다만 삼항연산자를 너무 길게 중첩하면 읽기 어려워질 수 있으므로, 간단한 조건 분기에 사용하는 것이 좋다.

 

즉, 삼항연산자는 짧은 조건 분기를 간단하게 표현하는 연산자이다.

 

5) 복합 대입 연산자

복합 대입 연산자는 계산과 대입을 한 번에 처리하는 연산자이다.

 

예를 들어 num += 3num = num + 3 과 같은 뜻이다.

  • +=
  • -=
  • *=
  • /=
  • %=

 

복합 대입 연산자는 같은 변수의 값을 계속 바꾸는 상황에서 자주 사용된다.

코드를 더 간단하게 만들고, 같은 패턴의 계산을 보기 쉽게 정리하는 데 도움이 된다.

 

즉, 복합 대입 연산자는 계산 결과를 다시 자기 자신에게 저장하는 연산자라고 볼 수 있다.

 


4. 정리

Variable에서는 형 변환, 변수와 메모리 구조, 출력 메소드, escape 문자, Scanner를 통해 자바의 기본 데이터 처리 방식을 정리할 수 있다.

Method에서는 메소드 실행 방식, 접근제한자, protected와 상속, 다른 패키지에서의 접근, static 메소드를 통해 메소드의 구조와 사용 범위를 정리할 수 있다.

Operator에서는 산술, 비교, 논리, 삼항, 복합 대입 연산자를 통해 계산과 조건 판단 방식을 정리할 수 있다.

 

이 내용들은 자바의 기초 문법이면서 이후에 배우게 되는 조건문, 반복문, 클래스와 객체 개념으로 이어지는 기본이 된다.


5. 느낀점

이번 수업에서는 메소드 부분이 가장 어렵게 느껴졌다.

메소드를 그냥 기능이라고만 생각했는데, 객체에 속한 메소드와 클래스에 속한 메소드가 나뉜다는 점이 신기했다. 특히 static 메소드는 객체를 만들지 않고도 사용할 수 있고, 일반 메소드는 객체를 생성해야 사용할 수 있다는 점이 인상적이었다.

 

또 접근제한자에 따라 메소드의 종류와 사용 범위가 달라진다는 점도 새롭게 느껴졌다. public, private, default, protected가 단순한 문법이 아니라 메소드를 어디까지 사용할 수 있는지를 정해주는 역할이라는 점이 흥미로웠다.

 

전체적으로 자바는 형식을 중요하게 생각하는 언어라는 느낌이 들었다. 변수 선언, 자료형, 객체 생성, 메소드 작성 방식처럼 정해진 규칙이 분명해서 쉽지는 않았지만, 그만큼 구조적으로 코드를 작성하게 만든다는 생각이 들었다. 연산자 부분은 자바스크립트에서 공부했던 내용과 비슷해서 비교적 익숙했지만, 메소드 부분은 조금 더 복습이 필요할 것 같다.