접근제어자
클래스, 필드, 메서드, 생성자 등에게 어떠한 특징을 부여하는 문법 요소다
사용 범위를 정의하는 역할을 한다
멤버 및 생성자의 접근 제어자
public : 동일 패키지의 모든 클래스 + 다른 패키지의 모든 클래스에서 사용 가능
protected : 동일 패키지의 모든 클래스 + 다른 패키지의 자식 클래스에서 사용 가능
default : 동일 패키지의 모든 클래스에서 사용 가능
private : 동일 클래스에서 사용 가능
아무것도 지정하지 않으면 default가 자동으로 설정된다
public > protected > default > private
* 다른 클래스 사용 시 객체를 생성해 줘야한다 상속받았을때는 객체를 생성할 필요 없다
package abc;
public class A {
public int a;
protected int b;
int c;
private int d;
void abc(){
// a, b, c, d 사용 가능
}
}
package abc;
class B {
// a, b, c 사용 가능
}
package bcd;
class C {
// a 사용 가능
}
package bcd;
class D extends A {
// a, b 사용 가능
}
클래스의 접근 지정자
클래스에서는 public, default 접근 지정자만 사용할 수 있다
쉽게보면 class 앞에 public이 붙느냐 안붙느냐 차이로 보면 된다
public이 있으면 다른 패키지에서 import해서 쓸 수 있는것이고
default면 다른 패키지에서 import할 수 없다는 것이다
* 클래스에 생성자가 없으면 자동으로 기본 생성자가 생성되는데
이때 기본 생성자의 접근지정자는 클래스의 접근지정자에 따라 동일하게 결정된다
물론 클래스와 생성자 각각 접근지정자를 줄 수 있다
하지만 클래스가 default라 import가 안된다면 생성자가 public이여도 객체생성 불가능
또 중요한건 같은 클래스라면 이게 의미가 없다 public이든 default든 다 객체생성 가능하다
패키지가 다를때
클래스 public, 생성자 public : import 가능, 객체 생성 가능
클래스 public, 생성자 default: import 가능, 객체 생성 불가능
클래스default, 생성자 public : import 불가능, 객체 생성 불가능
클래스 default, 생성자 default: import 불가능, 객체 생성 불가능
패키지가 같을때
public이든 default든 객체생성 가능
static제어자
클래스의 멤버(필드, 메서드, 이너클래스)에 사용되는 제어자이다
클래스의 멤버를 다른 클래스 내에서 사용하려면 객체를 생성해야하는데
객체 생성 하고 사용할 수 있는 상태가 되는 멤버를 인스턴스 멤버
객체 생성 없이 사용할 수 있는 상태가 되는 멤버를 정적 멤버
class A {
int a = 3;
static b = 5;
}
// a는 인스턴스 멤버
// b는 정적 멤버
객체를 생성해야하고 아니고는 메모리 저장 위치 때문에 그렇다
인스턴스 멤버는 참조변수를 써서 사용하기에 힙 영역에 값이 저장되기에 객체를 생성해야하고
정적 멤버는 클래스 내부에 저장 공간을 지니고 있기 때문에 객체를 생성할 필요가 없는 것이다
그런데 여기서 힙 영역에 보면 b가 생성되는 것을 볼 수 있는데 이건 메서드 때와 비슷하게
힙 영역에 주솟값만 저장되어있고 실제 값은 클래스 영역에 있다고 보면된다
마치 참조 자료형이 스택영역에 주솟값만 두고 실제 값은 힙영역에 있는것과 동일하다
정적 필드 객체 간 공유 변수의 성질
정적필드는 클래스 영역에 값이 저장된다고 했다
그래서 클래스 내에 static int a = 5; 라는 정적 필드가 있다고 하면
a1, a2 서로 다른 객체가 a1.a = 7; a2.a = 8 이렇게 적용했을때
a는 8이 된다 왜냐하면 같은 클래스 영역에 값을 공유하고 있기 때문이다
그래서 이런 기능을 살려서 모든 객체가 동일하게 적용받아야하는 필드에 적용한다
예를들면 은행 통장을 만들때 이자가 2%인데 이걸 static 인 정적 필드로 만들어두면
어떤 객체(통장) 이든 이자를 바꾸면 모든 통장의 이자율이 바뀌게 된다
인스턴스 메서드와 정적 메서드
메서드도 필드와 똑같이 인스턴스는 객체를 생성해서 써야하고
정적은 객체를 생성하지 않고도 사용할 수 있는 것이다
하지만 메서드는 인스턴스든 정적이든 클래스 영역에 존재한다
* 정적 메서드 내부에서는 정적 멤버와 정적 메서드만 사용가능하다
인스턴스 메서드 내부에서는 모두 사용 가능하다
정적 초기화 블록
인스턴스 필드의 초기화는 객체가 생성되는 시점에 초기화가 된다
하지만 정적 필드는 객체를 생성하지 않기에 생성자에서 초기화를 할 수 없다
이때 정적필드를 초기화 하기 위해 사용하는 것이 정적 초기화 블록이다
static { 클래스가 메모리에 로딩될 때 실행되는 내용 }
class A {
int a;
static int b;
static {
b = 5;
System.out.println("클래스가 로딩될 때 static bloc 실행"}
}
A( ) {
a = 3; //인스턴스 필드의 초기화 위치
}
}
static main( ) 메서드
우리가 맨 처음 아무것도 모르고 썼던 메인 메서드를 분석해 보자면
실제 프로그램 런을 시키면 main( ) 메서드가 제일 먼저 실행 되는데
이는 자바 가상 머신이 main( ) 메서드를 실행시켜주기 때문이다
main( ) 메서드는 정적 메서드 이므로 실행클래스명.main( ) 방식으로
자바 가상 머신이 호출하는 것 뿐이다
그래서 main( ) 메서드명도 마음데로 바꿀 수 없고
만약 인스턴스 메서드 였다면 자바 가상 머신도 객체를 생성한 뒤에
참조변수를 이용해서 main( ) 메서드를 호출해야한다
정리하면
자바 가상 머신은 프로그램을 실행할 때 실행 클래스명.main( ) 을 실행하므로
가장 먼저 실행되는 메서드인 main( )를 정적 메서드로 구성한 것이다
public class A {
public static void main(String[] args){
}
}
'Java' 카테고리의 다른 글
[Java] 자바 제어자2 (꼭 알아야 하는 내용만 뽑아서 정리) (0) | 2022.09.26 |
---|---|
[Java] 클래스의 상속과 다형성 (꼭 알아야 하는 내용만 뽑아서 정리) (0) | 2022.09.26 |
[Java] 클래스 외부 구성 요소 (꼭 알아야 하는 내용만 뽑아서 정리) (0) | 2022.09.26 |
[Java] 클래스 내부 구성 요소 (꼭 알아야 하는 내용만 뽑아서 정리) (0) | 2022.09.26 |
[Java] 클래스와 객체 (꼭 알아야 하는 내용만 뽑아서 정리) (0) | 2022.09.25 |