날아라쩡글이의 블로그입니다.

Static , 정적메소드, 정적변수 본문

중앙 HTA (2106기) story/java story

Static , 정적메소드, 정적변수

날아라쩡글이 2021. 9. 12. 20:13
반응형

value object / Data Transfer Object 

public class Student {  --->정보를 담고있는  클래스 :value Object / Data Transfer Object

  • int no;
  • String name;
  • Stirng dept;
  • int grade; 
  • String proffessor;
  • }
  • 필드 : 데이터만 담고있는 클래스로, 정보를 저장하는게 목적인 클래스이다. 
  • entity, domain Object, Java bean처럼 객체라는 다양한 이름을 가지고 있다. 

public class StudentService {   --->기능을 담고 있는 클래스 : Service Object라고 불리운다. 

  • void addnewStudent (Student student) {...}
  • Student getStudentByNo(int studentNo){...}
  • Student[] searchStudentByName(String name){...}
  • }
  • 관련된 업무로직이 구현된 객체를 생성할 때 사용되는 클래스로, 기능 구현 메소드들이 가득하다.
  • 메소드들이 많고, 필드가 거의 없고 기능위주이다. 역활이 나눠져있다
  • 이 부분은 책임의 분리와 같이 역활을 나눠 주는 것이다. 
  • ~~Service 객체라고 불린다. 

Static이란,

    • this의 경우 상속부분을 배울 때 추가적으로 설명을 하도록 함. 
    • Static(정적)은 고정된 것이라는 의미를 가지고 있다. 
    • Static키워드를 사용해서 Static변수와 Static메소드를 만들 수 있다. 
    • Static변수와 Static 메소드는 정적필드와 정적 메소드라고 불린다(클래스 변수, 클래스 메소드라고 불린다. )
    • 정적필드와 정적 메소드는 객체(인스턴스에 소속된 멤버가 아니라 클래스에 고정된 멤버이다. 
    • 클래스 로더가 클래스를 로딩해서 메모리에 적재할 때 클래스 별로 관리하는데, 클래스의 로딩이 끝나는 즉시 정적변수와 정적 메소드는 사용할 수 있게된다. 
    • public class Circle{
    • double pi; // 원주율
    • double r; // 반지름의 길이 
    • double getArea ( ) { return pi * r * r}//원의 너비 공식 
    • double getRoundLength( ) { return 2*pi*r}//원의 길이 공식}에 대해서 공식을 구한다고 하자.
    • public class CircleApp {
    • Circle circle1 = new Circle(3.14,5);
    • Circle circle2 = new Circle(3.14,10);
    • Circle circle3 = new Circle(3.14,15);
    • Circle circle4 = new Circle(3.14,20);
    • }

  • Circle의 클래스를 작성하고 Circle에 생성하는 new연산자를 이용하여, 객체 영역에 객체를 생성하였고 참조 변수에 주소값을 입력하였다. 그런데 객체내부의 멤버 변수중 pi의 경우 중복적인 형태를 갖고 있기 때문에 구별할 수 있는 데이터의 경우  r이 해당된다. 
  • 멤버변수가 공통적인 속성을 갖고있다면, 어떻게 코딩을 해야할까?
    공통적인 부분은 고정된값으로 클래스 변수에 입력을 시켰다. 클래스를 생성함과 동시에 즉시 사용가능 방법으로 만들었다. pi의 경우 값이 전부 동일해서 고유한 성질이 될 수 없다. 
  • 원을 구하기 위해 가지고 있어야하는 필수적인 값으로 파이는 객체마다 그 값을 가지고 있을 필요가 없다. 원의 너비나 지름을 구하기 위해 필요한 값으로 그럴 때 사용하는 것이 static이다. 원의 소속된 값으로 필요한 것이다. 
  • 객체마다 넣을 필요가 없는데 넣는 것은 잘 못된 코딩이다. 파이가 3.14라서 반지름이 5가 아닌것처럼 서로 관계가 없다. 그러나 파이는 필요하기 때문에 정적변수 class변수로 고정시켰다. 고정되었다는 것은 변수이름이 하나밖에 없다는 뜻이다. 
  • static 은 메모리 로딩시 static은 설계도 내부에서는 제외시키고, 객체 생성시 참여를 시키지 않고 class가 별도로 관리 시킨다. 
  •  설계도가 메모리에 로딩되면 정적변수와 정적 메소드는 즉시 사용가능한 상태로 만들며, 클래스가 별도로 관리시킨다. 정적변수와 정적메소드는 객체를 생성하지 않아도 사용이 가능하다. 정적변수와 정적메소드는 객체의 생성없이 바로 사용이 가능하기 때문에 정적변수와 정적메소드는 클래스이름. 변수명 or 클래스 이름. 메소드명()의 형식으로 바로 사용이 가능하다.
  • 메모리 로딩시 1번만 작성해도 완성하고, 클래스의 변수기 때문에 클래스가 관리하고 있기 때문에 클래스 이름으로 접근한다. 원의 너비를 구하기 위해 꼭 필요한 값으로, Circle내에 갖고있깅에는 너무 부담스러워서, Static으로 class에서 관리하도록 하여 객체 내의 pi가 사라지게 되며 클래스 로딩때 변수를 생성하여, 그 클래스를 불러올 때 상주해있어 static은 하나 밖에 만들 수가 없다. 
  • Circle. PI circle이 관리하는 정적변수 pi를 가져와라라는 신호이다. 
  • Ex) 
  • class 정기적금 { 
  •     이자율 3%; 
  •    예금주, 계좌번호, 잔액, 비밀번호, 가입일, 납입횟수 , 납입일자, 만료일
  • }
  • class 정기예금 { 
  •     이자율 2%; 
  •    예금주, 계좌번호, 잔액, 비밀번호, 가입일, 만료일
  • }
  • class 청약적금 { 
  •     이자율 1.5%; 
  •    예금주, 계좌번호, 잔액, 비밀번호, 가입일, 납입횟수 , 납입일자, 만료일, 청약대상
  • }
  • 적금은 3% 예금은 2% 청약적금은 1.5% 의 동일이자율을 가지고 있다. 그렇다면 동일이자율을 static(정적변수)으로 작성하고, 나머지는 필드로 구성하여 작성한다. (실제로 이렇게 프로그래밍은 되지않는다. 예시일뿐)

정적변수란

  • 변하지 않고, 객체에 상관없이 동일한 값이 나오는 것을 정적변수라고 한다. 정적변수로 하는 것이 좋다. 
  • pi의 경우 우주의 법칙이 바뀌지않는 경우 계속 파이는 3.14의 값을 갖는다. 그렇기 때문에 pi는 정적변수로 입력을 하였다. 

상수

  • Circle circle1 = new Circle(5); Circle.pi = 4; 변경이 가능 할 수 있다. 임의로 바꾸게 하고 싶지않을 때, 절대 변하지 않는 수로 입력을 해주는 것이 좋은데, 그것은 상수로 설정을 하는 것이다. 
  • static final double PI= 3.14 ;
  • 상수의 경우 변수명을 확인한다. 전부다 대문자로 작성을 해주어야하고, 거의 클래스 변수는 상수가 많다. 대문자로 시작하는 경우 --->1. 클래스 2.상수 이다, 특히 상수는 모든 글자를 대문자로 작성해주어야한다. 
  •  static 으로 클래스 변수화 시켜주고, final로 상수화를 시켜준다. 
  • static은 거의 상수로 입력하며, 클래스 변수, 정적변수의 경우 대체로 상수일 경우가 99.999999%상수로 입력이 되어있다. 
  • static final double PI=3.141592;
  • static final double INTEREST_REST = 0.003;
  • 상수 정의시 합성어에는 언더바를 사용하여 입력을 해준다. 

static 변수와 static메소드 

  • static(정적)은 고정된 것이라는 의미를 가지고 있다. 
  • static 키워드를 사용해서 static변수와 static메소드를 만들 수 있다
  • static 변수와 static메소드는 정적필드와 정적 메소드라고 부른다. 
  • 정적필드와 정적메소드는 객체 (인스턴스)에 소속된 멤버가 아니라 클래스에 고정된 멤버이다. 
  • 클래스 로더가 클래스를 로딩해서 메모리 영역에 적재할 때 클래스별로 관리하는데, 클래스의 로딩이 끝나는 즉시 정적변수와 정적메소드는 사용할 수 있게된다. 
  •  
  • static 영역의 경우 클래스가 할당된다. 가비지 컬렉터가 메모리를 관리하지 않는다. 프로그램 종료될 때까지 메모리에 유지된다
  • stack영역 지역변수가 할당된다. 매개변수가 할당된다. 닫는 괄호를 만나면 사라진다. 
  • heap영역 객체가 할당된다. 가비지컬렉터가 메모리를 관리하고, 아무도 참조하지않으면 가비지가 된다. 
  • 클래스 로더는 클래스 파일이 메모리에 로딩하는 프로그램이다. 
  • 수행문에 클래스 이름이 등장할 때 클래스 로더가 클래스 파일을 메모리에 로딩한다. 
  • 메모리에 로딩된 클래스(설계도)는 클래스 별로 관리한다. 
  • 클래스의 로딩이 완료되면 정적변수와 정적메소드는 즉시 사용가능하게 된다. 
  • static영역에 생성된 정적변수와 정적메소드도 클래스 별로 관리되기 때문에 정적변수와 정적메소드를 사용할 때는 클래스 이름으로 사용된다. 

정적멤버(클래스멤버)와 인스턴스멤버의 특징

구분 정적멤버 인스턴스멤버
메모리영역 static영역 객체영역,heap영역
사용시점 클래스 로딩 즉시 객체 생성 후 
공유여부 모든객체에 공유된 공유되지않음
생성갯수 단 한번만 생성됨 new연산자로 여러번 생성할 수 있음
소멸시점 프로그램 종료시 참조변수가 참조하지 않을 때

 

공용으로 사용할 경우 static, class멤버로 사용, 공용이 아닐 경우 인스턴스로 선언한다. 

static -->객체생성과 상관없이 사용이 가능한데, 객체 생성 후 사용가능한것은 포함할 수 없음, 당연히 객체는 그냥 사용이 가능한데, 객체 생성 후 사용가능한건 포함 할 수없다. 객체가 생성 후 사용가능한 것은 그냥 사용해도 가능함 어차피 객체 생성할 때 생성하니까, 당연히 설계도가 로딩될 때 객체 생성하기 때문에 클래스변수 클래스 메소드 사용가능하다. 객체 생성되었기 때문에 멤버변수 멤버메소드 사용가능하다. 아래 코딩을 보면 이해가 빠를 것이다.

정적변수를 왜 상수로 두는지에 대한 설명 

  • static의 경우 상수 선언시에 거의 사용한다. 상수는 한번 정해진 값을 변경할 수 없는 저장소이다. 언더바와 대문자로 상수로 정의한다. 
  • static int x는 공유하는 값으로 둔다. y는 객체가 별도로 있기 때문에 1이 출력되고, x의 경우 정적변수이기 때문에 값이 변경이 된다. 
  • 여기서 main이 static인 경우 메인이 설계되면 바로 사용이 가능해야하기 때문에 main이 static메소드였던것이다. 
  • 그리고 이후를 보면 s1의 increase의 경우 값이 계속 증가, printvalue의 경우 계속 값이 동일하게 된다는 것을 알 수 있다. class변수에서 관리를 하고 있기 때문에 값을 ++; 시켜서 변화가 있는 것인데, 
  • 공유한다는 것은 내가 바꾼 수가 유지되지않는다는 뜻이다. 
  • 이는 정말 위험한 발상이고, 내가 마트에서 화장실가기전에 음료수가 10개 있는 것을 확인하고 화장실을 갔는데, 그대로 음료수가 10개 있을 것이라고 생각하는 것을 값을 공유한다고 하는 것이다. 신중히 해야하며, 값을 변경 시킬수 있는 정적변수는 신경써야하며, 복잡도가 높아진다. x의 값을 변경가능하며, 공유한다는 것은 위험한 도박과 동일하다.
  • 일반적으로 정적변수는 읽기만 가능하도록 상수로 변경을 시킨다. 변경하지 않도록 상수로 두는 것이다. 

인스턴스 메소드와 정적 메소드의 기준 == 멤버변수

  • 인스턴스 메소드는 멤버변수와 상호작용을 하고, 객체가 갖고있는 고유한 값을 조회, 변경, 삭제를 한다. 멤버변수와 상호작용하는 것을 인스턴스 메소드라고 한다. 인스턴스 메소드는 객체마다 다른값 
  • 정적메소드의 경우 멤버변수와 상호작용을 하지 않는다. static은 고정적인 값을 의미한다. 멤버변수와 상호작용을 하지않는 메소드는 필요가 없다. 정적변수는 고칠 수 없는 수로 정적메소드는 읽어오기만 가능하다.  
  • 인스턴스 메소드만 작성한다고 생각하면된다. 읽는 것 또한 인스턴스 메소드에서도 가능하기 때문이다. 

정적메소드의 사용법

  • Math.random();0보다 같거나 크고 1보다 작은 실수를 출력하는 메소드
  • Math.round(); 반올림하는 수 
  • Arrays.sort(); 배열오름차순정렬
  • Arrays.toString();배열을 글자로 출력
  • 정적메소드의 경우 유틸리티 메소드에서 사용된다. 멤버변수와 상호작용이 없고, 여러객체와 함께 사용되는 기능들을 의미한다. 
  • helper클래스에 사용된다. 
  • java.Math()메소드의 경우 삼각함수, 근의 공식, 제곱근 구하는 방식에 사용이되는데 , 과학과 수학공식에서 수학계산때 자주사용이된다. 
  • 값만주면 다 만들어 낼 수 있는 곳에 사용을 한다. static 으로 만들어서 객체로 만들지 않고, 객체 생성없이 바로 생성하게 만든다. 멤버변수와 연관없는 것들을 static메소드로 만든다. 

유틸리티 클래스 

  • 자주 사용하는 메소드를 매번 만들어서 사용하는 것도 일이다. 프로젝트 시 프레임워크로 자주 사용한다. 

반복되는 문장을 자주사용할 경우 메소드로 만들 것하나 클릭 그리고 그 아래에도 문장을 작성해준다. 그리고 위에 코드를 클릭해서 왼쪽 마우스클릭 Refactor를 클릭-> extract Method를  클릭하고 메소드 이름으로 적절한 문장을 작성하면 자동으로 return까지도 전부 변경을 해준다 . 그 메소드로 전부 변환해준다. 

1. 중복코드가 사라져서 유지보수 때 코드를 많이 변경하지 않아도 되고, 가독성도 높아진다. 

2. 어떤코드가 어떤 일을 하는 지 수행문을 이름으로 작성할 수 있다. 엄청 복잡한 코드의 겨우 어떤 동작을 하는지 이름을 작성하여, 블록에 대해 특정 이름을 작성하여, 코드에 대한 작업과 결과를 한 눈에 알 수 있게 만들어 줄 수 있다. 

반응형

'중앙 HTA (2106기) story > java story' 카테고리의 다른 글

상속  (0) 2021.09.14
접근제한자 (modifier)  (0) 2021.09.13
생성자 (constructor)  (0) 2021.09.09
메소드  (0) 2021.09.08
객체 지향 언어  (0) 2021.09.06
Comments