모든 객체가 함께 사용하는 변수나 메서드를 만들 때 사용한다.
객체를 만들지 않아도, 클래스 이름만으로 사용할 수 있다.

위 예제와 같이 static키워드는 변수나 메서드에 사용할 수 있다.

static키워드로 선언된 변수와 메서드는 Method Area 에 저장되므로, 객체를 생성하지 않고, 클래스 이름만으로 Method Area 에서 가져다 쓸 수 있다.
객체를 만들때마다 생성되는 변수와 메서드이다.
객체를 생성한 후에만 사용할 수 있다.
각 객체가 개별적으로 값을 갖는다.
Heap영역에 위치한다.


위 예제와 같이 인스턴스 멤버의 경우 각 객체가 개별적으로 값을 갖기 때문에, 선언부에서 속성 및 메서드를 작성한 후

호출부에서 객체를 생성해야 사용할 수 있다.
즉 static은 모든 객체에게 동일한 값을 적용하여 활용하는것이기때문에 호출부에서 객체를 생성할 필요 없이 바로 사용할 수 있는 것이고, 인스턴스는 각각의 객체에게 서로 다른 고유한 값을 적용하여 활용하는 것이기 때문에 호출부에서 객체를 생성해야 사용할 수 있다.
인스턴스는 각 객체의 값이 공유되지 않는다.
static은 모든 객체가 같은 값을 공유한다.

Person 생성 시 population을 1씩 증가시키도록 생성자를 작성하고,

위 예제에서 보았듯 Person을 활용하여 객체 생성 시 population가 1씩 증가하게 된다.

따라서 호출부 객체 생성구문 아래에 위와 같은 출력문을 적어주면,

현재 인구수는 2가 된다. 확인을 위해 p3라는 객체를 생성하여, 다시 출력해보자.


객체가 하나 더 생성되니 인구 수가 늘어나는 모습을 확인할 수 있다.
static은 반드시 공용으로 활용할 변수에 사용해야 한다.
static 메서드에서는 인스턴스 변수에 접근할 수 없다. (인스턴스 멤버를 사용하기 위해서는 객체가 생성되어있어야 하기 때문이다.)
static은 반드시 필요한 상황에만 사용해야 한다. static변수와 메서드는 프로그램이 종료될 때 까지 메모리에 유지된다.
따라서 static키워드를 남용할 시 메모리 낭비로 이어진다.
final을 사용하면, 변수의 값을 딱 한 번만 설정할 수 있다.
final키워드를 사용하면, 
final로 선언된 클래스는 상속할 수 없다.
final로 선언된 메서드는 수정할 수 없다.(오버라이딩 불가)
+Java에서는 대문자로 표현하는것이 관례이다.
프로그램 실행 중 절대 변경되면 안되기 때문에 static final을 이용해 외부로부터의 변경 요소를 제거한 뒤 값을 고정하여 선언한다.
예시로 원주율이 있다. 원주율은 절대 변해선 안되는 값이기 때문이다.


위 예제와 같이 활용할 수 있다.
내부 상태를 변경할 수 없는 객체이다.
final을 속성에 활용하며, 세터 없이 설계한다.
변경이 필요할 경우 새로운 객체를 만들어야 한다.
ex) String, Integer, 래퍼클래스 등이 있다.
불변 객체를 만들 때 호출부에서 객체 생성시에만 final키워드를 사용할 시 참조 변경은 막지만 내부 상태 변경은 막지 않기 때문에, 올바른 불변 객체가 아니다.
예)
호출부

선언부

위 예제의 경우 호출부에서 final을 이용해 객체를 생성하였으나, 아래 이미지와 같이 radius의 값을 변경해도 문제 없이 작동한다.

이는 선언부에서 radius의 값을 final로 고정해주지 않았기 때문이며, 따라서 해당 객체는 올바른 불변객체가 아니다. 그러므로 올바른 불변객체로 만들기 위해서는 다음과 같다.

선언부에서 radius의 값을 final로 고정해주면 호출부에선 다음과 같은 변화가 생긴다.

본래 c1객체의 radius값을 변경해도 아무 문제가 되지 않았지만, 선언부에서 값을 고정해주니 빨간 줄이 생기며, 값을 변경할 수 없다고 알린다.
즉 올바른 불변객체를 만들기 위해서는, 객체를 생성하는 호출부와, 객체와 관련된 선언부의 모든 속성값을 final로 고정해줘야한다.
앞서 올바른 불변객체에 대하여 알아보았는데, 객체를 사용하다보면, 필수불가결하게 내부 상태의 변경이 필요한 상황이 생길 수 있다.
그럴 땐 두 가지 방법을 활용하여 해결할 수 있다.

c1의 radius값 변경이 필요할 경우 c2라는 객체를 새로 생성하며, 필요한 값을 할당하면 된다.
위 코드는 선언부에서 changeRadius라는 기능을 생성한 것이다.
changeRadius사용시 newRadius(새로운 값)를 할당하도록하고,
반환 값으로 할당된 값(newRadius를 담은 Circle의 생성자를 호출하여 반환한다.
이를 호출부에서 사용할 땐 다음과 같이 사용할 수 있다.

객체를 생성한다는 골자는 같지만, 1번의 경우 아예 새로운 객체를 생성하는 것이고, 2번의 경우 객체c2에서 changeRadius를 사용해 변경된 newRadius값을 받아서 객체를 생성한다는 차이가 있다.
2주차 5강 궁금점 : 불변객체의 내부 상태 변경이 필요한 경우 직접 변경이 불가하기에, 객체를 새로 생성해야한다.
이 때 직접 생성자를 호출하여 생성하는 방법이 있고, 변경값을 받아 생성자를 반환하는 기능을 구현하여 객체를 생성하는 방법 두 가지가 있다고 이해했는데, 제대로 이해한것이 맞는지...?
제대로 이해한게 맞다면, 결국 객체를 새로 생성한다는 점은 동일한데, 기능을 활용하는 방법의 특별한 이점이 있는지?~~
아니면 내가 잘못 이해하고 있는지.
생성자를 직접 이용해 객체를 생성할 경우 처음 할당한 값이 고정된다.
그러나 메서드를 이용해 객체를 생성할 경우 이름 지정이 가능하고, 여러 기능을 추가할 수 있어서 1번 경우보다 훨씬 유연하게 사용할 수 있다. 이에 따라 유지보수도 편리하며, 이름을 지정할 수 있기 때문에, 다른 사람이 봤을 때 어떤 기능을 하는 객체인지도 보다 쉽게 판단할 수 있다.