ABOUT ME

  • 메서드,싱글톤,static,상수
    JAVA 2021. 7. 22. 22:34

    메서드

    메서드는 객체의 동작(기능)에 해당하는 중괄호{} 블럭이다.

    중괄호 블럭은 이름을 가지고 있는데 이것이 메서드 이름이다. 메서드를 호출하게 * 되면 이 중괄호 블럭에 정의돼 실행문들이 일괄적으로 실행하게 된다.

     

    메서드는

    1) 필드를 읽거나 수정

    2) 다른 객체를 생성해서 다양한 기능을 수행하기도 한다. 메서드는 객체간의 데이터 전달의 수단으로 사용된다.

    메서드는 외부로부터 매개값을 전달 받을 수 있고 실행한 후의 임의의 값을 전달할 수 있다. 

     

    1. 메서드의 선언

    메서드의 선언은 선언부와 실행블럭으로 구성된다.

    선언부에는 리턴타입, 메서드이름 매개변수등을 선언하고 메서드선언부를 메서드 시그니처(signature)라고도 한다.

    2. 리턴타입

    리턴타입은 메서드가 실행한 후 리턴하는 값의 데이터타입을 말한다.

    메서드는 리턴값이 있을 수도 있고 없을 수도 있다.

    리턴값이 없을 경우에는 리턴타입을 void 라고 선언하고 있을 경우에는 데이터타입(기본타입 및 참조타입포함) * * 3. 메서드이름의 명명규칙

    1) 숫자로 시작하면 안되고 $와 _를 제외한 특수문자는 사용이 불가하다.

    2) 관례적으로 메서드이름은 소문자로 시작한다.

    3) 서로 다른 단어가 혼용이 될 경우에는 해당 단어의 첫 글자는 대문자로 작성한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public class Calcurator {
     
        // 메서드의 변수형이 앞에 붙을 시 return값이 꼭 있어야 한다.
        // void의 경우는 return값이 올 수 없다.
        void powerOn() {
            System.out.println("파워온");
        }
     
        void powerOff() {
            System.out.println("파워오프");
        }
     
        int plus(int x, int y) {
            int result = x + y;
            return result;
        }
     
        double divide(double x, int y) {
            // return으로 int매개변수를 넘겨서 double형태로 가므로
            // 묵시적형변환이여서 따로 형변환 하지 않아도 된다.
            return x / y;
     
            // 자바에서는 리턴문 뒤에는 실행문이 올 수가 없다.
        }
     
        String modelName() {
            return "LG 계산기";
        }
     
    }
     
    cs

    static1 정적 블럭, 정적 메서드

    정적메서드와 정적블럭 사용시에 주의할 점

    정적메서드와 정적블럭을 선언할 때 주의할 점은 객체가 생성되지 않아도

    즉, 객체가 없더라도 사용할 수 있다는 특징 때문에 정적메서드와 정적블럭 내부에 인스턴스필드나 인스턴스 멤버를 사용할 수 없다.

    또한, 객체 자신의 참조인 this키워드도 사용 불가능하다.

    정적메서드와 정적블럭에서 인스턴스(객체)멤버를 사용하고 싶다면 객체를 먼저 생성하고

    참조변수(객체)로 접근해야 한다.

    또한 , main메서드도 정적멤버이기 때문에 동일한 규칙이 적용된다.

    이런 이유로 main메서드에서 객체생성없이 인스턴스필드,인스턴스메서드를 바로 사용할 수 없다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public class CarMain {
     
        static int speed;
     
        static void run() {
            System.out.println("현재 속도는 " + speed + "km/h 입니다!");
        }
     
        int speed2;
     
        void run2() {
            System.out.println("현재 속도는 " + speed + "km/h 입니다!");
        }
     
        public static void main(String[] args) {
     
            speed = 100;
            run();
     
            CarMain car1 = new CarMain();
            car1.speed2 = 100;
            car1.run2();
     
            Car car2 = new Car();
            System.out.println(car2.company);
        }
     
    }
     
    class Car {
     
        String company = "포르쉐";
        String model = "911카레라";
     
    }
    cs

     

    static2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public class Television {
     
        static String company = "LGE";
        static String model = "OLED";
        static String info; // LGE-OLED
     
        // 정적(초기화)블럭
        // 정적블럭은 클래스가 메모리에 로딩될 때 자동으로 실행되는 블럭이다.
        // 정적블럭은 클래스 내부에 여러개 선언되도 상관없다. 클래스가 메모리로
        // 로딩될 때 선언된 순서로 실행된다.
        
        static {
            info = company + "-" + model;
        }
     
        static {
            info = model + "-" + company;
        }
     
        public static void main(String[] args) {
     
            System.out.println(Television.company);
            System.out.println(Television.model);
            System.out.println(Television.company + "-" + Television.model);
            System.out.println(Television.info);
            
        }
     
     
    }
     
    cs

    static3

    정적멤버와 static

    정적은 "고정된" 이란 의미를 가지고 있다.

    정적멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않아도 사용할 수 있는 필드와 메서드를 말한다.

    이름을 각각 정적멤버, 정적메서드라고 부른다.

     

    정적멤버는 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 소속된 멤버이기 때문에 클래스멤버라고도 한다.

    정적필드와 정적메서드는 클래스에 고정된 멤버이므로 클래스로더가 클래스파일 (~.class)을 로딩해서 메서드메모리영역에 적재할 떄 클래스별로 관리된다.

     

    필드를 선언할 때 인스턴스 필드로 선언할 것인가?

    정적필드로 선언할 것인가의 판단기준은 객체마다 독립적으로 가지고 있어야 할 데이터라면 인스턴스멤버로 선언하고 객체마다 공통으로 사용되는 공용적인 데이터라면 정적 필드로 선언 하는 것이 좋다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    public class Calcurator {
     
        // 필드
        static double pi = 3.14592;
     
        // 생성자
     
        // 메서드
        static int plus(int x, int y) {
            return x + y;
        }
     
    }
     
    public class CalcuratorMain {
     
        public static void main(String[] args) {
     
            System.out.println(Calcurator.pi);
            System.out.println(Calcurator.plus(1010));
            
            Calcurator cal1 = new Calcurator();
            Calcurator cal2 = new Calcurator();
            
            System.out.println(cal1.pi);
            
            //클래스의 변수(static사용)도 같이 바껴버린다.
            cal1.pi = 100;
            System.out.println(cal1.pi);
            System.out.println(Calcurator.pi);
            
            //그래서 static으로 공통으로 사용하는 변수들은 상수 final 선언하는게 좋다.
            
        }
     
    }
     
     
    cs

    싱글톤(singleton)

    프로그램에서 단 한개의 객체만 생성하도록 해야 하는 경우가 있다.

    객체가 단 한개만 생성 된다고 해서 이러한 객체를 싱글톤이라고 한다.

     

    싱글톤을 만들려면

    1. 외부에서 new연산자로 생성자를 호출할 수 없도록 막아야 하는데 이는 생성자를 호출한 수 만큼 객체가 생성되기 때문이다. 생성자를 외부에서 호출할 수 없도록 하려면 생성자 앞에 private라는 접근제한자를 붙여 주면 된다.

     

    2. 자신의 타입인 정적필드를 하나 선언하고 자신의 객체를 생성하고 초기화 한다. 그리고 내부에서 new연산자로 생성자를 호출해서 객체를 생성하고 이 정적필드(singleton)을 private접근제한자로 선언해서 외부에서 필드값을 변경하지 못하도록 한다.

     

    3. 외부에서 직접 자신의 객체에 접근하지 못하도록 막는 대신에 외부에서 호출할 수 있도록 정적 메서드 getter메서드 getInstance()를 선언하고 정적필드인 singleton에서 참조하고 있는 자신의 객체를 리턴해 준다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    //class는 public, default만 사용가능하다.
    public class Singleton {
        
        //다른클래스에서 생성자 호출 불가능
        private Singleton() {}
        
        //private: 자신 클래스에서 만든 유일한 생성자.
        //static: 이 생성자를 가져가서 쓰려면 클래스메서드(static)로 밖에 불가능하다.
        //        이 때 만든 생성자를 static으로 만들어줘야 메모리에 존재하여 사용할 수 있다.
        private static Singleton singleton = new Singleton();
        
        static Singleton getInstance(){
            return singleton;
        }
        
        void xxx() {
            System.out.println("싱글톤 메서드 호출!");
        }
    }
     
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    //java패키지안에 - util패키지안에 Calendar클래스를 가져옴
    import java.util.Calendar;
     
    public class SingletonMain {
     
        public static void main(String[] args) {
            
     
            //class인 Singleton은 public이므로 클래스메서드(static이 붙은)는 
            //클래스.메서드() 로 사용가능
            Singleton sg1 = Singleton.getInstance();
            
            //클래스.메서드() 로 하나밖에 없는 생성자를 불러 인스턴스 메서드도 사용가능해짐
            sg1.xxx();
            
            //sg1과 똑같은 new Singleton 즉, 같은 생성자로서 주소값이 같다.
            //sg1 == sg2  true
            Singleton sg2 = Singleton.getInstance();
            
            //주소값 호출(들어있는게 주소값-이 주소값을 참조하여 값을 가져옴(참조형))
            System.out.println(sg1);
            System.out.println(sg2);
            
            if(sg1 == sg2) {
                System.out.println("동일 객체입니다.");
            }else {
                System.out.println("다른 객체입니다.");
            }
            
            //대표적인 싱글톤패턴
            //인스턴스를 만들려면 클래스메서드를 사용해야 한다.
            Calendar cal1 = Calendar.getInstance();
            Calendar cal2 = Calendar.getInstance();
            
            
            //다른 객체인 이유: 객체만드는 메서드가 오버라이딩되어 주소값이 다르다
            //시간이 지날때마다 주소값이 달라짐(아마 시간값이 달라져서 가져오는 주소들도 계속 변하나보다)
            if(cal1 == cal2) {
                System.out.println("동일 객체입니다.");
            }else {
                System.out.println("다른 객체입니다.");
            }
            
            //동일 객체이지만 시간이 달라서 주소값도 다르다.
            System.out.println(cal1.toString());
            System.out.println(cal2.toString());
        
        }
     
    }
     
    cs

    FINAL1 상수

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package com.lack206.ex07_final;
     
    public class Earth {
     
        static final double EARTH_RADIUS = 6400;
        static final double EARTH_SURFACE_AREA;
     
        static {
            EARTH_SURFACE_AREA = 4 * Math.PI * EARTH_RADIUS * EARTH_RADIUS;
        }
    }
     
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class EarthMain {
     
        public static void main(String[] args) {
     
            System.out.println("지구의 반지름 = " + Earth.EARTH_RADIUS + "km");
            System.out.println("지구의 표면적 = " + Earth.EARTH_SURFACE_AREA + "km^2");
            System.out.println(Math.PI);
        }
     
    }
     
    cs

    FINAL2 상수

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public class Korean {
     
        static final String NATION = "대한민국";
        String name;
        String ssn;
     
        public Korean(String name, String ssn) {
            this.name = name;
            this.ssn = ssn;
        }
     
        // 최상위 Object클래스의 메서드: 주소값을 나타내는 메서드
    //    @Override
    //    public String toString() {
    //        // TODO Auto-generated method stub
    //        return super.toString();    //그냥 부모클래스(super: 현재는 Object) 값을 return
    //    }
     
    //    @Override
        public String toString() {
            return "국적: " + NATION + ", 이름:" + this.name + ", 주민:" + this.ssn;
        }
     
    }
     
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class KoreanMain {
     
        public static void main(String[] args) {
            
            Korean kor1 = new Korean("소향""680405-2345678");
            System.out.println(Korean.NATION);
            System.out.println(kor1.name);
            System.out.println(kor1.ssn);
        
            //상수값 바꾸기 불가능
            //Korean.NATION = "미국";
            //kor1.NATION = "미국";
            
            //변수는 당연히 가능
            kor1.name = "홍길동";
            System.out.println(kor1.name);
            
            Korean kor2 = new Korean("나얼""623455-1234568");
            System.out.println(Korean.NATION);
            System.out.println(kor2.name);
            System.out.println(kor2.ssn);
            
            //둘 다 이 변수가 가지고 있는 값인 주소를 나타낸다.
            //현재 Korean 클래스에서 toString의 메서드를 재정의(overriding)
            //메서드가 Korean 것으로 뜸.
            System.out.println(kor1.toString());
            System.out.println(kor1);
            System.out.println(kor2);
     
        }
        
    }
     
    cs

    'JAVA' 카테고리의 다른 글

    댓글

Designed by Tistory.