Home Java 프로그래밍 교육 2일차
Post
Cancel

Java 프로그래밍 교육 2일차

자바는 변수 선언 시 데이터타입을 명시하여 변수의 타입을 제한한다.
다른 언어 javascript나 python에서는 var 키워드를 사용해 변수 선언 시 타입에 제한을 두지 않기도 한다.


기본형 (원시 타입, Primitive Data Type)

분류 자료형기본값대표 자료형
문자  char ’\u0000(빈문자 1개) 
숫자정수  byte, short, int, long 0, 0, 0, 0L int
 실수 double, float 0.0f, 0.0d double
논리형  boolean(true/false) false 

클래스 데이터 타입 (Class Data Type, Reference Data Type) 
[참고] https://juran-devblog.tistory.com/139


디렉터리와 패키지, 폴더 모두 같은 의미이다. 하지만 경로 포기 시 조금 다른 점이 있다.

  • 소스코드 : com…XX.java
  • 파일경로 : src.com…XX.java

모든 패키지를 표기하는 파일 경로와는 다르게 소스코드의 위치를 나타낼 땐 src 패키지는 제외하고 표기해도 된다. 소스코드는 모두 src 패키지 아래 존재하기 때문이다.


로컬 변수(temporary variable)
메서드 블럭 안에서 선언한 변수로 메서드의 생명주기와 같다. 메서드 시작 시 생성되어 종료 시 소멸된다. 로컬 변수는 기본값이 없다. 

필드(field)
클래스 내 메서드 밖에 선언된 변수로 클래스 내 어디서나 사용 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
public class A{
   int i;
   
   public method1 {
      sysout(i); // 초기화 되지 않은 i는 아직 메모리에 올라가지 않아 사용 불가하다.
   }
   
   public method2 {
      A a = new A(); // 변수 생성, 초기화 후 
      sysout(a.i); // 사용 가능하다.
   }
}

[참고] 인스턴스 변수, 로컬 변수, 클래스 변수 https://itellyhood.tistory.com/32


논리연산자 &&(논리곱)와 &(곱)의 차이 

  • 둘 다 앞과 뒤 문장이 true일 때만 true 반환
  • A && B : A가 false이면 B를 실행하지 않고 바로 false를 반환한다.
  • A & B : A가 false여도 B 실행

논리연산자 ||(논리합)와 |(합)의 차이

  • 둘 다 앞 뒤 문장 중 하나라도 true 이면 true 반환
  • A || B : A가 true이면 B를 실행하지 않고 바로 true를 반환한다.
  • A | B : A가 true여도 B 실행

그냥 합과 곱은 연산자 앞 뒤 문장 모두 실행하기에 컴파일시 문제가 되는 문장이 있으면 예외가 발생한다. 논리합과 논리곱은 앞의 문장이 조건이 충족되면 뒤의 문장은 실행하지 않는다. 따라서 주로 예외 발생 가능한 문장은 논리합과 논리곱 뒤에 배치한다.

이해는 잘 안가지만 나는 이런 경우 예시를 다음과 같이 판단했다.

값이 있는지 확인 후 값을 판단해야할 때 값 여부 체크 로직을 A에 넣고 그 값에 대한 판단(크기나 동치비교)은 B에 넣는다.
만약 이전에 값의 여부를 따지기 않았거나 A에 값을 사용하는 문장이 온다면 값이 없는 경우 오류가 날 것이다. 먼저 값이 있는지 체크 후(A) 그 조건을 만족시킨다면 그 다음 그 값이 맞는 값인지 판단하는(B) 것이다.
즉, 조건을 걸 때 A > B 순으로 확인을 해야한다면 논리연산자를 사용하는게 좋지 않을까..

그리고 속도 측면에서 아주 미세한 차이로 논리합, 논리곱이 그냥 합과 곱보다 빠르다고 한다.


캡슐화(Encapsulation) 
데이터 보호를 위해 외부에서 값에 바로 접근하지 못하도록 감싸는 것이다.

image

클래스 내부 멤버에 바로 접근하지 못한다. 외부에서 public 메서드들을 통해 내부 멤버에 접근할 수 있다.

  • 필드는 private으로 작성한다.
  • 필드에 직접 지정이 아닌 getter, setter등의 메서드를 통해 필드값을 넣고 받는다. 이렇게 메서드로 접근하면 setter나 메서드 내에 값 체크 로직을 추가하여 타당한 값만 받을 수 있다.
    실무에서 생성자보다는 setter를 더 사용한다고 한다. 생성자는 인자의 순서에 따라 그 의미가 달라지기 때문이다.


배열(Array)
같은 데이터 타입을 가진 여러 값들이 하나의 변수를 통해 처리된다. 배열은 크기가 정해져있다.

1
2
3
4
5
int [] arr; // 배열 선언
arr = new int[3]; // 크기 명시하여 배열 생성
int [] arr = new int[3]; // 혹은 선언과 생성을 동시에

int[] arr = {1, 2, 3};

image

  1. Stack에 배열 arr을 위한 공간이 할당된다. 이때 배열은 똑같이 객체임으로 기본값은 null이다.
  2. Heap에 배열 객체가 생성되고 각 영역 모두 기본값(int 기본값은 0)으로 초기화된다. 
  3. 각 배열 원소에 대한 명시적 초기화가 이뤄진 후 Heap에 할당된 메모리 주소를 Stack에 다시 저장한다.


1
2
3
4
int arr1[] = {1, 2, 3};
int arr2[] = {'a', 'b'};

arr1 = arr2;

Stack에는 arr1과 arr2 배열을 위한 공간에 초기화된 값이 모두 저장되어있다. 하지만 arr1=arr2 를 통해 arr1에는 기존의 arr1 Stack 주소값이 arr2의 Stack 주소값으로 업데이트된다. 이때 Stack의 arr1에 대한 참조는 끊기게 되지만 값은 계속 남아있는다. 이런 값은 쓰레기값 이라 하며 GC에 의해 해제된다.

This post is licensed under CC BY 4.0 by the author.