2,3주차_자바프로그래밍기초(1)

이상민·2023년 9월 4일
0

JVM (Java Virtual Machine)

JVM: 자바를 실행하기 위한 가상머신으로 OS에 종속 받지 않고 CPU가 Java를 인식, 실행할 수 있게 하는 가상머신이다.

*.java 코드는 CPU가 인식을 하지 못하므로 기계어로 컴파일해줘야한다. java 소스코드(.java)로 작성된 코드를 java compiler가 JVM이 읽을 수 있는 .class(java bytecode)로 변환한다. 이후 linker를 통해 코드를 묶고 JVM이 OS가 bytecode를 이해할 수 있도록 해석한다.

JVM 특징

  • 장점

    1. 플랫폼 독립성: java byte codeJVM이 있는 모든 플랫폼에서 실행 될 수 있다.
    2. 메모리 관리: JVM가비지 컬렉터를 사용하여 사용하지 않는 객체가 차지하는 메모리를 자동으로 할당 해제. -> 메모리 누수 방지, 개발자의 메모리 관리 단순화
  • 단점

    1. JVM을 거치고 OS와 하드웨어를 거치기 때문에 다른 애플리케이션에 비해 속도가 느림

C++ vs Java

객체할당

C++

Matrix m(5,5); // stack 할당: stack 영역에서 실행 되고 스택을 탈출하면 자동으로 변수가 제거됨
Matrix *p = new Matrix; // heap 할당: p라는 변수는 stack, a변수가 가르키는 메모리 주소는 heap영역에 할당

Java

Matrix m(5,5); // 문법 오류; stack할당 불가
Matrix p = new Matrix; // heap할당; java는 p앞에 *안붙임

자바에서 객체의 stack할당이 되지 않는이유:
cpp의 경우 heap영역에 할당된 객체를 소멸자를 이용해서 직접 제거하지만, 자바의 경우 jvm에서 자동으로 삭제하기 때문에 stack 할당을 허용하면 자동으로 삭제를 할 수 없기 때문

자바 문법

변수

변수란 컴퓨터 주메모리에 할당된 기억 공간으로 크기타입을 갖는다. (예: int a 변수 a가 정수형 4byte 공간임을 선언)
자바 언어에는 두 가지 변수 타입이 존재함

  • 기본(primitive) 타입
  • 객체(object) 타입 (기본 타입의 변수들의 집합체)

기본 객체 타입(int8 16 32 64, float 32,...와 같은 cpu에서 연산을 제공하는 객체들)은 stack heap 할당이 가능 그러나 객체 타입(기본타입 변수의 집합)은 오직 heap에 할당해야 함.

자바 실습

  • main1
    public static void main(String[] args) {
        String s1 = "Hello, Java!";
        System.out.print("s1= "); System.out.println(s1);
        String s2 = String.format("%s, %s!","Hello","Java");
        System.out.print("s2= "); System.out.println(s2);

        int len1 = s1.length();
        int len2 = s2.length();
        System.out.println("len1 = "+len1); //string과 int의 + 연산을 하기 위해 int를 string으로 형변환하는 연산이 자동으로 적용됨
        System.out.println("len2 = "+len2);

        boolean b1 = s1.equals(s1); // s1과 s1의 내용 비교
        boolean b2 = s1.equals(s2); // s1 과 s2의 ''
        boolean b3 = (s1 == s2); // 객체의 주소를 비교

        System.out.println("s1.equals(s1) = " + b1); //bool과 string의 연산을 위해 bool을 str로 형 변환
        System.out.println("s1.equals(s2) = " + b2);
        System.out.println("(s1==s2) = "+ b3);

    }
  • main1 실행결과
    s1= Hello, Java!
    s2= Hello, Java!
    len1 = 12
    len2 = 12
    s1.equals(s1) = true
    s1.equals(s2) = true
    (s1==s2) = false
    
    Process finished with exit code 0
  • main2
    public static void main(String[] args) {
        String istr = "1234";
        String dstr = "12.34";

        int ival = Integer.parseInt(istr);//string -> int 형변환
        double dval = Double.parseDouble(dstr);//string -> Double 형변환
        System.out.println("before : "+ival+", " + dval);

        ival = ival + 1111;
        dval = dval + 11.11;
        String istr2 = String.valueOf(ival);
        String dstr2 = String.valueOf(dval);

        System.out.println("after : "+ istr2 + ", " + dstr2);
    }
  • main 2 실행결과
before : 1234, 12.34
after : 2345, 23.45

Static 선언

java에서는 Static이라는 키워드를 사용하여 Static변수Static메소드를 만들 수 있는데 다른말로 정적필드정적 메소드라고도한다. (클래스 멤버) 정적 필드와 정적 메소드는 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 고정된 멤버. 그렇기에 클래스 로더가 클래스를 로딩해서 메소드 메모리 영역에 적재할때 클래스별로 관리된다.

  • 변수 앞에 static이 붙는 경우
    그 변수가 속한 클래스의 인스턴스들 사이에서 공유되는 변수가 되며, 그 변수는 객체 소속이 아닌 클래스 소속이다.(개별 객체 수준에서 static 변수를 위한 공간할당 없음: 객체(in heap)와 다른 곳(in static area)에 할당 된다는 의미)

  • 메쏘드 정의 앞에 static
    Static 메소드는 재정의(override)할 수 없음. 객체의 dinamic 변수들에 접근할 수 없고 오직 클래스 소속 static 변수들 만 접근 가능

  • 클래스와 static 선언 관계
    {} 으로 감싼 블록 안에서 선언된 클래스는 모두 dynamic 클래스,{} 밖에 선언 된 클래스는 static 클래스, 또한 클래스 내부에 static 선언을 통해 inner 클래스를 선언할 수 있으며 이러한 클래스는 outter 클래스의 대표 객체에 속한다.

 public static void main(String[] args) {
        class Nested{
            private int dy; // 인스턴스 변수: 인스턴스에 속한 변수, 객체와 함께 소멸
            private static int dx;//클래스 변수: 변수가 속한 클래스의 인스
            //턴스(객체) 사이 공유 되는 변수, 객체가 소멸 돼도 남아 있음
            public  int get_dy(){ return dy;}
            public  static int get_dx(){return dx;}
            public Nested(int cy, int cx){dy = cy; dx = cx;}
            public class InnerD{
                public int get_dy(){return dy;}
                public int sum(){return dy+dx;}
            }
            public static class InnerS{
                public int get_dx(){return dx;}
                //public int get_dy(){return dy;}:이 코드는 작동이 안됨,
                //어떤 인스턴스(객체)의 인스턴스 변수를 참조하는 지 정보도 모를 뿐더러 
                //정적 클래스의 외부 클래스의 인스턴스 변수를 직접 접근하는 것은 자바 구조상 불가능
           
            }

        }
    public static void main(String[] args) {
        Nested m1 = new Nested(1, 2);
        Nested m2 = new Nested( 3,4);
        System.out.println("m1.get_dy() = "+m1.get_dy() +" m1.get_dx() = " + m1.get_dx());
        System.out.println("m2.get_dy() = "+m2.get_dy() +" m2.get_dx() = " + m2.get_dx());
        Nested.InnerD d1 = m1.new InnerD(); //dynamic
        Nested.InnerS s1 = new Nested.InnerS(); //static
        Nested.InnerD d2 = m2.new InnerD();
        Nested.InnerS s2 = new Nested.InnerS();
        System.out.println("d1.get_dy() = "+d1.get_dy() +" d1.get_dx() = " + s1.get_dx() + " d1.sum() = " + d1.sum());
        System.out.println("d2.get_dy() = "+d2.get_dy() +" d2.get_dx() = " + s2.get_dx()+ " d2.sum() = " + d2.sum());
    }
}
  • 실행 결과
m1.get_dy() = 1 m1.get_dx() = 4
m2.get_dy() = 3 m2.get_dx() = 4
d1.get_dy() = 1 d1.get_dx() = 4 d1.sum() = 5
d2.get_dy() = 3 d2.get_dx() = 4 d2.sum() = 7

접근 제한자

접근 제한자 모두 필드 또는 method 앞에 붙여서 선언한다.

  • private

    소속 클래스 외부에서 해당 필드 또는 method를 참조할 수 없게함

  • public

    소속 클래스 외부 어디에서든지 참조가능

  • protected

    서브클래스가 해당 필드 또는 method를 참조하는 것을 허용
    또한 default access 또한 허용한다. 다른 패키지에서도 해당 클래스를 상속 받으면 default 접근허용

  • default access

    필드 또는 method 앞에 접근 제한자를 지정하지 않는 경우. 패키지 내부 어디에서든지 접근 가능(클래스 간 공유하는 상태변수 지정할 때 유용)

profile
잘하자

0개의 댓글