[Java] 명품 Java Programming 정리 - 4장

근이의 개발일기·2024년 8월 19일
0
post-thumbnail

4장

클래스와 객체

  • 클래스 구성 Untitled
    • 클래스 선언
      • class 키워드로 선언
      • 클래스는 { 로 시작하여 }로 닫으면서 이 블럭 안에 모든 필드와 메소드 구현
      • 클래스 접근 권한 public ← 다른 클래스에서 접근할 수 있음을 나타냄
      • 주의! 클래스와 객체는 같지 않음!
    • 필드와 메소드
      • 필드: 객체 내에 값을 저장하는 멤버 변수
      • 메소드: 멤버 함수이며 객체의 행동(행위)를 구현
    • 필드의 접근 지정자
      • 필드나 메소드 앞에 붙어 다른 클래스의 접근 허용을 표시
    • 생성자
      • 클래스의 이름과 동일한 특별한 메소드
      • 객체가 생성될 때 자동으로 한번 호출되는 메소드
      • 개발자는 객체를 초기화하는데 필요한 코드 작성
  • 객체 생성 및 접근
    • 객체에 대한 레퍼런스 변수 선언

      • ex) Circle pizza; //레퍼런스 변수 선언
    • 객체 생성 / 초기화

      • 클래스 타입 크기의 힙 공간의 메모리 할당
      • 모두 null값으로 채워 넣음
      • 반드시 new 키워드를 이용하여 생성
      • 객체 내 생성자 코드 실행 ex) pizza = new Circle(); //C.E 괄호 꼭 붙이기! new circle → 객체 생성 circle() →객체 초기화 (생성자 실행)
    • 객체 접근
      - 객체의 멤버 접근
      - 점(.) 연산자 이용

          ex) [pizza.name](http://pizza.name) = “자바 피자”;
          

      Untitled

  • 객체의 생성과 활용 예제
    public class Circle{
        int radius;
        String name;
        public Circle() {};
        public double getArea(){
            return 3.14*radius*radius;
        }
    
        public static void main(String[] args) {
            Circle pizza;
            pizza = new Circle();
            pizza.radius = 10;
            pizza.name = "자바피자";
            double area = pizza.getArea();
            System.out.println(pizza.name + "의 면적은 "+ area);
        }
    }
    • 출력 결과: 자바피자의 면적은 314.0

중요 생성자와 기본 생성자**

  • 중요 생성자의 특징
    • 객체가 생성될 떄 초기화를 위해 실행되는 메소드
    • 생성자 이름은 클래스 이름과 반드시 동일
    • 생성자 여러 개 작성 가능; 오버로딩 가능 (매개변수 part가 다름)
    • 주의! 생성자는 new를 통해(단독 사용x) 객체를 생성할 때, 반드시 호출되고 객체당 한 번 호출 ㄴ 생성자는 하나 이상 선언되어야 함 ㄴ 개발자가 생성자를 작성x, 컴파일러가 자동으로 기본생성자를 삽입
    • 생성자는 리턴타입을 지정할 수 없음
  • 생성자 사용 예시: 두개의 생성자를 가진 클래스
    public class Circle{
        int radius;
        String name;
        public Circle() {
            radius = 1; name="";
        };
        public Circle(int r, String n) {
            radius = r; name=n;
        };
        public double getArea(){
            return 3.14*radius*radius;
        }
    
        public static void main(String[] args) {
            Circle pizza = new Circle(10, "자바피자");
    
            double area = pizza.getArea();
            System.out.println(pizza.name + "의 면적은 "+ area);
        }
    }
    public class Book {
        String title;
        String author;
    
        public Book(String t) {
            title =t;author="unknown";
        }
        public Book(String t, String a){
            title=t; author=a;
        }
    
        public static void main(String[] args) {
            Book littlePrince=new Book("어린왕자", "생텍쥐페리");
            Book loveStory=new Book("춘향전");
            System.out.println(littlePrince.title+" "+littlePrince.author);
            System.out.println(loveStory.title+" "+loveStory.author);
        }
    }
    • 생성자 오버로딩를 통해 new로 객체 생성시 매개변수로 값을 전달하여 초기화함을 알 수 있다.
  • 기본 생성자 (디폴트 생성자)
    • 매개 변수 없이 아무 작업 없이 단순 리턴하는 생성자
    • 클래스에 생성자가 하나도 선언되지 않은 경우, 컴파일러에 의해 자동으로 삽입 Untitled
      • 주의! 생성자의 접근 지정자는 클래스의 접근 지정자를 따른다!
    • 클래스에 생성자를 하나라도 선언한 경우, 기본 생성자가 자동 생성되지 않는다 Untitled

this 레퍼런스

  • 객체 자신에 대한 레퍼런스 this
    • 컴파일러에 의해 자동 관리, 개발자는 사용하기만 하면 됨
    • 클래스 안에서 자신을 나타내는 레퍼런스로써 사용됨
  • this의 사용 예시 및 필요성
    1. this.member_name 형태의 사용

      ![Untitled](https://prod-files-secure.s3.us-west-2.amazonaws.com/d48a8b3a-0902-461a-8e65-1e3bd3ed9699/ced2fd64-d6a6-4aa6-8685-677fe0071fb2/Untitled.png)

      Untitled

      ㄴ 객체의 멤버 변수와 메소드 변수의 이름이 같은 경우

      → 이름을 바꿔주지 않고 객체의 멤버변수를 this.meber_name의 형식으로 써주면 이름이 같아도 구분하면서 동작함

      ㄴ다른 메소드 호출 시 객체 자신의 레퍼런스를 전달할 때

    2. return this; 사용

      ㄴ 다른 메소드 호출 시 객체 자신의 레퍼런스를 반환할 때

    3. this() 사용 / 중요 같은 클래스의 다른 생성자 호출

      ㄴ 클래스 내의 다른 생성자 호출

      ㄴ 생성자 내에서만 사용가능하고 반드시 생성자의 맨 첫줄에서 수행; 컴파일러가 첫문장에 두었을 떄 판단하는 뭔가가 있음

      ㄴC.E 생성자의 첫 번째 문장에서 사용하지 않을 시

      Untitled

    • this(””, ””); // Book()생성자가 Book(String title, String author)생성자를 호출하게 하고 “”, ””값을 전달함

    • this(title, “작자미상”); //Book(String title)생성자가 Book(String title, String author)생성자를 호출하게 하고 “”, ”작자미상”값을 전달함

      → 추가적인 생성을 하는 것이 아님 결국 하나의 객체 생성

      → 값을 갱신하는 변수를 줄이기 좋음

객체의 치환과 배열 사용

  • 객체의 치환(=연산자 사용): 객체의 복사가 아닌 레퍼런스의 복사로써 같은 객체를 가르키게 된다. 주의! 생성하지 않고 레퍼런스 변수로써만 사용가능함!!

Untitled

  • 객체 배열 생성 및 사용 Untitled
    • 클래스 배열에 대한 레퍼런스 변수를 선언 후 레퍼런스 배열을 new를 통해 생성해준다

    • 중요 객체의 배열에서 배열의 원소는 객체가 아니며 객체에 대한 레퍼런스이다. 그러므로 객체 배열 생성 후 다시 원소의 개수만큼 객체를 생성해서 배열의 각 원소에 지정해야한다.

    • 주의! 배열의 각 원소 객체를 따로 생성하고 초기화해야한다 (생성자를 통해)

      Untitled

  • 객체 배열 예시
    public class Circle{
        int radius;
        String name;
        public Circle() {
            this(1, "");
        };
        public Circle(int r){
            this(r,"");
        }
        public Circle(int r, String n) {
            radius = r; name=n;
        };
        public double getArea(){
            return 3.14*radius*radius;
        }
    
        public static void main(String[] args) {
            Circle []c=new Circle[5];
            
            for(int i = 0; i<c.length;i++)
                c[i]=new Circle(i);
            
            for(int i=0; i<c.length;i++)
                System.out.println(i+"번쨰의 면적은 "+ c[i].getArea());
        }
    }
    import java.util.Scanner;
    public class Book {
        String title;
        String author;
        public Book(){
            this("","");
        }
        public Book(String t) {
            this(t,"unknown");
        }
        public Book(String t, String a){
            title=t; author=a;
        }
    
        public static void main(String[] args) {
            Book [] book = new Book[2];
    
            Scanner scanner = new Scanner(System.in);
            for(int i=0;i<book.length;i++){
                System.out.print("제목>>");
                String title = scanner.nextLine();
                System.out.print("저자>>");
                String author = scanner.nextLine();
                book[i] = new Book(title,author);
            }
            for(int i=0;i<book.length;i++)
                System.out.print("("+book[i].title+", "+book[i].author+")");
    
            scanner.close();
        }

메소드 형식과 중요 인자 전달

  • 메소드 형식
    • 클래스의 멤버함수, c/c++과 동일하나 접근 지정자가 붙음
    • 자바의 모든 메소드는 반드시 클래스 안에 있어야함 Untitled
  • 중요 인자전달 방식
    • primitive건 reference건 다르게 동작하긴 하지만 변수의 메모리 안의 비트가 복사되는 방식 ← 둘 다 call by value!!
    1. 기본 타입의 값 전달

      • 값이 복사되어 전달됨
      • 메소드의 매개변수가 변경되어도 호출한 실인자 값은 변경되지 않음

      Untitled

    2. 레퍼런스 타입의 값 (객체 혹은 배열) 전달

      • 객체나 배열의 레퍼런스만 전달
        • 객체 혹은 배열이 복사되어 전달되는 것이 아님
      • 메소드의 매개변수와 호출한 실인자 객체나 배열 공유

      Untitled

      Untitled

  • 인자로 배열이 전달되는 예시
    public class ArrayParameterEx {
        static void replaceSpace(char a[]){
            for(int i=0; i<a.length; i++){
                if(a[i]==' ')
                    a[i]=',';
            }
        }
        static void printCharArray(char a[]){
            for(int i=0;i<a.length;i++)
                System.out.print(a[i]);
            System.out.println();
        }
    
        public static void main(String[] args) {
            char c[] = {'I',' ','a','m',' ','H','o','g','e','u','n','.'};
            printCharArray(c);
            replaceSpace(c);
            printCharArray(c);
        }
    }
  • String도 클래스이기 때문에 reference 타입으로 전달됨

메소드 오버로딩

  • 메소드 오버로딩: 이름이 같은 메소드 작성
    • 매개변수의 개수나 타입이 서로다름

      • 주의! 개수 같고 타입이 달라도 됨
    • 주의! 리턴 타입은 오버로딩과 관련이 없음
      - 컴파일러는 메소드의 이름과 매개변수만을 검사함

      Untitled

      Untitled

    • 예시로 print/printf/println 함수를 보면 오버로딩 된것을 볼 수 있다

      Java Platform, Standard Edition Java API Reference

객체의 소멸과 가비지 컬렉션

  • 객체 소멸: new에 의해 할당된 객체 메모리를 JVM의 가용 메모리로 되돌려 주는 행위
    • 객체 소멸은 JVM의 고유한 역할로써 임의로 응용프로그램에서 객체 소멸할 수 없음
    • 자바 개발자에게는 좋은 기능; 상당히 뛰어난 알고리즘으로 알아서 반환해 주므로 객체 소멸에 대해 신경쓰지 않아도 됨
  • 가비지: 자신을 가리키는 레퍼런스가 하나도 없는 객체
    • 프로그램에서 사용할 수 없게 된 메모리이다.
    • 한번 가비지가 되면 다시는 참조할 수가 없다.
  • 가비지 컬렉션: JVM의 가비지 컬렉터가 자동으로 가비지를 수집하고 회수하여 가용 메모리로 반환한다.
    • 가비지 발생 시 바로 반환하는 것이 아닌 시분할 기법, 다양한 가중치와 임계치등을 사용한 알고리즘을 이용해서 반환
    • 가용 메모리량이 일정 수준 이하로 떨어질 때 실행되기도
    • 가비지 컬렉션 스레드에 의해 수행
  • 가비지의 발생과 힙 공간
    1. 가비지의 처리: main함수 내 지역변수 reference나 객체의 feild에서의 reference는 null을 넣어서 가비지 처리해주면 메모리 효과가 있을 수 있다. 함수의 지역변수에서는 효과가 거의 없다.

    2. System.gc();

      • System 혹은 Runtime 객체의 gc() 메소드 호출
      • 이 코드는 JVM에 가비지 컬렉션 요청을 하는 것이나 받아들일지 말지는 JVM이 전적으로 판단 → 정교하게 실행하기에 선택적 개입이 어려움
    3. Heap 공간의 사용: JVM은 각각 하나의 APP을 관리한다. 한꺼번에 JVM이 모든 프로그램을 관리하지 않는다.

      Untitled

    4. 그렇기 때문에 Heap공간의 사용에 대해 프로그램 당 그렇게 크지 않은 공간을 준다. → 설정항목의 환경변수에서 힙공간을 얼마나 사용할지 바꾸어 줄 수 있다. // dialog JVM arguments 명령행 파라미터로 heap-size를 지정한다.

    5. 그러나, 현재 백엔드 개발에서는 가상 클라우드 공간을 사용하기 때문에 traffic이 몰리면 설정을 통해 공간을 늘려주기만 하면 된다. 실제로 resource는 무한대라고 생각하고 server를 구축하기도 한다.

패키지 개념

  • 패키지
    • 관련 있는 클래스 파일(컴파일된 .class)을 저장하는 디렉터리(폴더)

    • 자바 응용프로그램은 하나 이상의 패키지로 구성

    • 이름은 소문자로 작성해준다

      Untitled

      Untitled

    • 🟥 패키지 내부의 .java 파일들은 첫 줄에 package a;로 파일이 속한 패키지 명을 적어준다. a안의 c에 있다면 a.c와 같이 나타낸다.

    • 🟨 src는 디폴트 패키지로 기능하며 그 위치에 클래스를 만들면 하위 패키지에 접근이 가능하지만 패키지 내부에서는 접근할 수 없다.

    • 🟩 같은 패키지 내의 클래스끼리는 서로 일반적으로 이름으로 호출하여 사용하면 된다.

    • 🟩 다른 패키지 내의 클래스는 package명까지 써주어야 한다. 패키지 a의 AA클래스를 사용하려면 a.AA로 호출하여햐 한다.

      • 🟪 우리가 지금까지 사용했던 Scanner 클래스의 경우 원래는 java.util.Scanner의 풀네임으로 사용해야하지만, import java.util.Scanner; 를 통해서 다른 package java.util에 있는 클래스 Scanner를 패키지 명 없이 사용한다.
      • 🟪 만약 다른 패키지에서 클래스 이름이 겹치면 전부 써주어야한다.
        • ex) java.vir.Scanner / java.util.Scanner의 경우 이름이 같기떄문에 풀네임을 사용해야한다.

          package Chapter13_package1;
           
          import Chapter13_package2.PackageTest2;
           //Chapter13_package1과 Chapter13_package2는 
           //둘다 PackageTest라는 같은 이름의 클래스를 사용한다
          public class PackageTest {
           
              public static void main(String[] args) {
                  // TODO Auto-generated method stub
                  
                  // Chapter13_package2 의 PackageTest 클래스를 사용
                  // 클래스 충돌이 발생하기 때문에 패키지를 명시 필요
                  Chapter13_package2.PackageTest pk = new Chapter13_package2.PackageTest();
                  pk.package_function();
           
                  // Chapter13_package2 의 PackageTest2 클래스를 사용
                  // import 를 해주었기 때문에 클래스명만 사용
                  PackageTest2 pt2 = new PackageTest2();
                  pt2.package_function();
                  
                  // Chapter13_package1 의 PackageTest 클래스를 사용
                  // 클래스 명을 작성하지 않으면 현재 패키지의 클래스를 참조
                  package_function();
              }
              
              public static void package_function() {
                  System.out.println("패키지1 의 함수");
              }
          }
          
      • java.lang 패키지의 경우 기본적으로 import되기 때문에 그냥 사용하면 된다.

접근지정자

  • 자바의 접근 지정자 4가지
    • private, 디폴트(접근지정자 생략), protected, public
    • 접근: 식별자가 나온 곳에서 정의된 곳으로 접근
    • 접근 오류: 접근 지정자 밖 호출! 컴파일 에러이다.
  • 접근 지정자의 목적
    • 클래스나 일부 멤버를 공개하여 다른 클래스에서 접근하도록 허용
    • 객체 지향 언어의 캡슐화는 멤버를 보호하는 목적
      • 접근 지정을 통해 캡술화에 묶인 보호를 일부 해제
  • 접근 지정자에 따른 클래스나 멤버의 공개범위 Untitled
  • 클래스 접근 지정
    • 다른 클래스에서 사용하도록 허용할 지 지정

      • 클래스에는 public과 디폴트 접근지정자를 부여할 수 있지만, 클래스 내부의 클래스는 하나의 멤버로 취급하기에 4가지 접근 지정자를 부여한다.
    • public 클래스

      • 다른 모든 클래스에게 접근 허용
      • ex) public class World { … }
    • 디폴트 클래스
      - package-private라고도 함
      - 같은 패키지의 클래스에만 접근 허용
      - ex) class Local { … }

      Untitled

  • 멤버 접근 지정
    • public 멤버

      • 패키지에 관계 없이 모든 클래스에게 접근 허용
    • private 멤버

      • 동일 클래스 내에만 접근 허용
      • 그 이외의 클래스에서는 접근 불가 (상속 받은 서브 클래스에서도 접근 불가)
    • protected 멤버

      • 같은 패키지 내의 다른 모든 클래스에게 접근 허용
      • 주의! 상속 받은 서브 클래스는 다른 패키지에 있어도 접근 가능
    • default 멤버
      - 같은 패키지 내의 다른 클래스에게 접근 허용

      Untitled

  • 멤버 접근 지정자의 예시
    • public 접근 지정 예시 Untitled
      • 모든 위치의 클래스에서 접근이 가능하다
      • 모든 멤버나 클래스를 public으로 두면 대형 프로그램일 때 간략화가 되지 않는다. 변수가 필요하면 전역화하는 것과 같음
      • private로 하려고 하고 거기서 차차 default나 protected를 고려하여서 범위를 넓혀준다.
    • protected 접근 지정 예시 Untitled
      • 같은 패키지 내의 클래스나 상속한 클래스에서 접근이 가능하다
      • 주의! 위의 예시를 보면 B가 부모 클래스이고, D가 자식 클래스 이다. B의 n과 g()를 보면 protected로 접근 지정이 되어있으므로 D는 B와 다른 패키지에 있어도 접근이 가능하다. (자식 객체로서만 접근 가능)
      • 당연히 같은 패키지 내에서는 접근 가능하다
    • default 접근 지정 예시 Untitled
      • 같은 패키지의 클래스 내에서 접근이 가능하다
    • private 접근 지정 예시 Untitled
      • 자기를 포함한 클래스 내부에서만 접근 가능
  • 멤버의 접근 지정자 예시
    class Sample {
        public int a;
        private int b;
        int c;
    }
    
    public class AccessEx {
        public static void main(String[] args) {
            Sample aClass = new Sample();
            aClass.a = 10;
            aClass.b = 10;
            aClass.c = 10;
        }
    }
    • b가 private이기에 컴파일 오류가 난다.
    • 프롬프트: java: b has private access in Sample

중요 static 개념

  • static 멤버
    • 객체마다 생기는 것이 아닌 클래스당 하나만 생성
      • 클래스 멤버라고도 부름
      • 클래스의 멤버에만 붙이고 지역변수에는 붙이지 않는다.
    • 주의! 객체를 생성하지 않고 사용가능 Untitled
  • non-static멤버와 static 멤버의 특성
    • non-static 멤버의 특성
      • 공간적 특성 - 멤버들은 객체마다 독립적으로 별도 존재
        • 인스턴스 멤버라고 부름
      • 시간적 특성 - 필드와 메소드는 객체 생성 후 비로소 사용 가능
        • 객체가 생길 떄 멤버도 생성
        • 객체가 사라지면 멤버도 사라짐
      • 비공유 특성 - 멤버들은 다른 객체에 의해 공유되지 않고 배타적
    • static 멤버의 특성
      • 공간적 특성 - 멤버들은 클래스 당 하나씩만 생성
        • 멤버는 객체 내부가 아닌 별도의 공간(클래스 코드가 적재되는 메모리)에 생성
        • 클래스 멤버라고 부름
      • 시간적 특성 - 멤버들은 클래스가 로딩될 때 공간 할당
        • 클래스가 로딩될때는 클래스가 처음 언급된 순간
          • static 필드나 메소드의 언급, 클래스 선언 등등 관련된 무언가를 모두 포함
        • 객체가 생기기 전에 이미 생성
        • 객체가 생기기 전에도 사용 가능
        • 객체가 사려져도 멤버는 사라지지 않음
        • 멤버는 프로그램이 종료될 때 사라짐
      • 공유의 특성 - 멤버들은 동일한 클래스의 모든 객체에 의해 공유 Untitled
        • 클래스 기준: 클래스가 언급된 순간 바로 클래스는 로딩이 된다. 로딩 후에 클래스 코드가 코드영역에 옮겨지고 m과 f()를 가지는 클래스 객체도 코드영역에 만들어 진다.
        • 주의! 멤버 접근 2가지 방식 (둘 다 가능!)
          • StaticSample.m ← 클래스 명으로 접근 가능
          • s1.m ← 객체 이름으로도 접근 가능
        • 객체 기준: new를 통해 생성해주는 순간 객체가 메모리에 생성된다.
  • static의 활용
    • 전역 변수와 전역 함수를 만들 때 활용
      • 전역 변수나 전역 함수는 static으로 클래스에 작성
      • ex) Math 클래스: java.lang.Math → Math.random() Math: 클래스, random(): static 메소드 → 클래스 생성 불필요, static 메소드의 사용
        • 모든 필드와 메소드가 public static으로 선언되어있음 → 클래스를 생성하지 않고 함수 사용 → 다른 모든 클래스에서 사용할 수 있음
    • 공유 멤버를 작성할 때 사용
      • static 필드나 메소드는 하나만 생성, 클래스의 객체들이 공유해서 사용할 수 있다
  • static 멤버를 객체의 멤버로 접근하는 사례 Untitled
    • 객체의 멤버인 g()와 h()를 통해서 static 멤버 m에 대해 접근하고 값을 바꿔주고 있다
  • static 멤버를 클래스 이름으로 접근하는 사례 Untitled
    • 객체 이름 s1과 클래스이름 StaticSample을 통해 f()를 호출해 보고 있다
  • static멤버의 사용 예시
    class Calc{
        public static int abs(int a) { return a>0?a:-a; }
        public static int max(int a,int b){ return (a>b)?a:b; }
        public static int min(int a, int b){ return (a>b)?b:a; }
    }
    public class CalEx {
        public static void main(String[] args) {
            System.out.println(Calc.abs(-5));
            System.out.println(Calc.max(10,8));
            System.out.println(Calc.min(-3,-8));
        }
    }
    • Calc 클래스의 객체를 생성하지 않고 static 함수를 사용하고 있음
  • 주의! static 메소드의 제약 조건
    • static 메소드는 non-static 멤버를 접근할 수 없음
      • 객체가 생성되지 않은 상황에서도 static 메소드는 실행될 수 있기 때문에 non-static 메소드와 필드 사용 불가

      • 반대로, non-static메소드는 static멤버 사용 가능

      • 주의! main함수도 static메소드이기 때문에 인스턴스 변수 사용 불가!!

      • this.이 명시적으로 써져있지 않아도 본인의 필드를 가리킬때 this.이 있다고 생각!

      • static 메소드에서 객체를 생성하고나면 non-static에 접근할 수 있음

        Untitled

    • 중요 static 메소드는 this 사용 불가
      • 마찬가지로 객체가 생성되지 않은 상황에서도 호출이 가능하므로 현재 객체를 가리키는 this 사용 불가능

        Untitled

  • static의 활용 예시
    import java.util.Scanner;
    class CurrencyConverter {
        private static double rate;
        public static double toDollar(double won){
        return won/rate;
        }
        public static double toKWR(double dollar){
            return dollar*rate;
        }
        public static void setRate(double r){
            rate = r;
        }
    }
    public class StaticMember {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.print("환율(1달러)>> ");
            double rate = scanner.nextDouble();
            CurrencyConverter.setRate(rate);
            System.out.println("백만원은 $"+CurrencyConverter.toDollar(100_0000)+"입니다.");
            System.out.println("$100는 "+CurrencyConverter.toKWR(100)+"원입니다.");
            scanner.close();
        }
    }
    • 출력 결과: 환율(1달러)>> 1392
      백만원은 $718.3908045977012입니다.
      $100는 139200.0원입니다.

final의 사용

  • final 클래스 - 클래스 상속 불가 Untitled
  • final 메소드 - 오버라이딩 불가 Untitled
  • final 필드, 상수 선언
    • 상수를 선언할 때 사용

    • 주의! 필드 선언: (접근지정자) (static) (final) (type) 변수명

      Untitled

    • 상수 필드는 선언 시에 초기 값을 지정해야 한다

    • 상수 필드는 실행 중에 값을 변경할 수 없다

      Untitled

    • 지역변수에는 접근지정자와 static을 사용하지 않는다!

원본 노션 링크

https://believed-poinsettia-f0f.notion.site/4-ee015a23d2424e419cc971b8cdbc5db0?pvs=4

0개의 댓글