JAVA(Programmers) - 1

Java 공부 시작!

맨날 공부 시작 시작 말만 하다가 이제서야 제대로 시작하려고 한다. 나의 주력언어로 쓸 것이니 처음 부터 하나하나 꼼꼼히 보도록 할 것이다.


Java의 탄생 - 출처

Java의 특징 - 출처


JVM(Java Virtual Machine)이란?

JVM은 Java 프로그램뿐 아니라 Java bytecode로 컴파일된 다른 언어로 작성된 프로그램도 컴퓨터에서 실행할 수 있도록 하는 가상 시스템. - 출처: wikipedia

위에서 Java는 어느 플랫폼에서도 실행이 가능하다고 했다. 과연 왜 그럴까?

java1_1

 그림 출처 

그 이유는 바로 C와는 달리 Java는 OS에 상관없이 JVM위에서 실행되기 때문이다. C처럼 어떤 OS인지에 따라 영향을 받을 수 있는게 아니기 때문에 플랫폼에 독립적이다. Java 에 대한 유명한 말 중 하나인 “Write once, run erveywhere” 이 있는데 어떤 OS인지에 상관없이 동일한 코드가 어느 곳에서든 동일하게 실행이 된다는 뜻이다. 물론 JVM 자체는 OS에 영향을 받기 때문에 해당 OS에 맞는 JVM으로 설치를 해야한다.


C같은 경우는 소스코드가 컴파일하면 .obj라는 assembly code 가 되고, 어셈블러로 machine code가 된다. Java의 실행단계는 간략하게 말하자면 아래와 같다. (아래 사진과 문항은 해당 블로그를 참고했다)

java1_2

사진 출처

  1. Hello.java라는 소스코드를 Java compiler로 컴파일 한다.
  2. 컴파일이 되면, Hello.class라는 Java byte code가 생성된다.
  3. Java byte code(Hello.class)를 JVM이 읽고 실행하게 된다.
  4. Java Class Loader : JVM안으로 class파일들을 load한다. Loading 된 class파일들은 Runtime Data Area에 배치된다.
    • Runtime Data Area : JVM이 프로그램을 수행하기 위해 OS로 부터 별도로 할당 받은 메모리 공간.
  5. Execution Engine : Load된 Class의 ByteCode를 실행하는 Runtime Module이 바로 Execution Engine. Execution Engine은 Java bytecode를 명령어 단위로 읽어서 실행.
  6. 실행 엔진은 Java bytecode를 명령어 단위로 읽어서 실행.


Java Array

// array declare
final static int arrSize = 5;
int[] arrInt = new int[arrSize];
int[] arrInt2 = new int[]{1,2,3,4,5};
int[] arrInt3 = {1,2,3,4,5};

배열의 크기를 반드시 명시해줘야한다.


Array length

int[] arr1 = new int[20];
int arrLength = arr1.length; // arr1 길이 : 20


Array length vs String length

근데 배열을 배우다가 문득 들었던 생각인데, 분명 나는 Java에서 length()라는 method를 쓴 기억이 있는데 배열에서는 length를 써야했었다. 뭐가 다르길래 하나는 method를 쓰고, 하나는 instance variable를 쓰는 것일까 싶어서 찾아봤다.

해당 링크를 참고하여 정리해봤다.


String literal vs new declare

해당 의문을 해결하기 위해서는 먼저 이것부터 알아야 한다. String object는 2가지 방법으로 선언할 수 있다.

String str1 = "Hello"; // literal
String str2 = new String("Hello"); // new operator

하나는 constructor를 안쓰고 선언했고, 하나는 constructor로 선언했다. 여기서 분석을 해보자.


이렇게 분석을 해봤다. 아직까지는 둘의 차이가 뭔지 잘 모를 수 있다. 더 자세히 말해보도록 하겠다.

먼저 literal선언을 하게 되면, 해당 문자열은 Heap영역의 String Constant Pool에 저장이 된다. 근데 또 다른 literal선언을 했는데 같은 문자열 값을 썼다면, String Constant Pool에 이미 존재하는 값이므로 2번째로 선언된 reference variable은 1번째로 선언된 reference variable와 같은 곳을 가리킨다.

그러나 new String()으로 선언을 했다면, String Constant Pool에 같은 문자열이 있든지 말든지 무조건 새로운 instance를 생성하는 것이다.

이렇게 설명만 들으면 이해가 잘 안갔기에 코드로 구현을 해봤다. Java에는 System.identityHashCode("reference variable")라는 함수가 있다.System.identityHashCode()는 객체의 고유한 hashcode를 리턴하는 method이다. reference variable어디를 가리키는지를 출력을 해준다. literal선언된 2개의 변수가 가리키는 instance가 같다면, 해당 함수의 결과 값 또한 같아야 할 것이다.

public class StringTest{
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = "Hi";
        System.out.println("변경 전 str1(Hello literal)->" + System.identityHashCode(str1));

        String str4 = new String("Hello");
        String str5 = new String("Hello");
        str1 = str1 + " World!";

        String str6 = "Hello World!";
        
        System.out.println("변경 후 str1(Hello World literal)->" + System.identityHashCode(str1));
        System.out.println("str2(Hello literal)->" + System.identityHashCode(str2));
        System.out.println("str3(Hi)->" + System.identityHashCode(str3));
        System.out.println("str4(Hello new)->" + System.identityHashCode(str4));
        System.out.println("str5(Hello new)->" + System.identityHashCode(str5));       
        System.out.println("str6(Hello World literal)->" + System.identityHashCode(str6));       
    }
}
programmers git:(main) ✗ java StringTest      
변경 전 str1(Hello literal)->705927765
변경 후 str1(Hello World literal)->366712642
str2(Hello literal)->705927765
str3(Hi)->1829164700
str4(Hello new)->2018699554
str5(Hello new)->1311053135
str6(Hello World literal)->118352462

java1_3

reference variable은 Java의 Stack영역에 생긴다. 위 그림은 코드의 reference variable들이 참조하고 있는 곳을 나타낸 것이다.


참고 사이트

https://starkying.tistory.com/entry/what-is-java-string-pool

https://www.guru99.com/java-stack-heap.html

https://changhozz.tistory.com/entry/String%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%98-%ED%8A%B9%EC%A7%95

https://www.tutorialspoint.com/what-are-the-differences-between-length-and-length-in-java

https://pienguin.tistory.com/entry/JAVA-%EC%9E%90%EB%B0%94-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EC%8B%A4%ED%96%89-%EA%B3%BC%EC%A0%95-%EB%B0%8F-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0