[Java] static method, static block
[Java] static method, static block
static 메소드
지금까지 main()메소드에서 자신의 클래스나 다른 클래스에 있는 메소드를 호출하려면
반드시 객체를 생성했어야만 했습니다.
그런데 생각해보면 System.out.println()메소드는 System클래스 안에 있는 메소드인데
지금까지 객체한번 생성안하고 잘 사용해왔습니다.
그럴수 있었던 이유는 println()이 static 메소드 이었기 때문입니다.
예를 들어 다음과 같은 코드가 있다고 하면
public class staticEx {
static String name;
public static void main(String[] ar) {
staticEx.staticMethod(); // This is a staticMethod
staticEx.staticMethod2("Teemo"); // inputed champion: Teemo
}
public static void staticMethod() {
System.out.println("This is a staticMethod");
}
public static void staticMethod2(String champion) {
name = champion;
System.out.println("inputed champion: " + name);
}
}
staticMethod()와 staticMethod2()메소드는 둘다 static메소드이기 때문에
staticEx 클래스의 객체를 만들지 않고도 잘 사용한 것을 볼 수 있습니다.
static 메소드를 쓸 때 주의할 점은, 클래스 변수(static이 붙은 인스턴스 변수)만이
static 메소드에서 사용될 수 있는 변수라는 것입니다.
위의 코드에서 name변수를 정의할 때 static을 빼버리면 에러가 납니다.
하지만 static을 함부로 붙이면 안됩니다.
클래스 변수가 되면 모든 객체에서 하나의 값을 바라보기 때문입니다.
public class staticEx2 {
static String name;
public staticEx2() {}
public staticEx2(String name) {
staticEx2.name = name;
}
public static void main(String[] ar) {
staticEx2 ex = new staticEx2();
ex.checkStaticVariable();
// ex1.name: Teemo
// staticEx2.name: Teemo
// ex2.name: Jinx
// staticEx2.name: Jinx
// ex1.name: Jinx
}
public void checkStaticVariable() {
staticEx2 ex1 = new staticEx2("Teemo");
System.out.println("ex1.name: " + ex1.name);
System.out.println("staticEx2.name: " + staticEx2.name);
staticEx2 ex2 = new staticEx2("Jinx");
System.out.println("ex2.name: " + ex2.name);
System.out.println("staticEx2.name: " + staticEx2.name);
System.out.println("ex1.name: " + ex1.name);
}
}
위의 코드에서는 ex1.name을 “teemo”로 정의했지만,
ex2.name을 “Jinx”로 정의하자 ex1.name도 “Jinx”가 되는 걸 볼 수 있습니다.
즉, 객체명.name 으로 접근하는 것은 크게 의미가 없습니다.
올바르게 클래스변수에 접근하는 방법은 클래스명.name인 staticEx2.name이 되겠습니다.
The static field staticEx2.name should be accessed in a static way
static 블록
static 블록은 어떤 클래스 객체가 생성될 때 딱 한번만 불러지는 코드입니다.
class staticBlock{
static String name = "teemo";
public staticBlock(){
System.out.println("This is StaticBlock Constructor");
}
static {
System.out.println("First static block");
name = "Jinx";
}
static {
System.out.println("Second static block");
name = "Rengar";
}
public static String getData() {
return name;
}
}
public class staticEx3 {
public static void main(String[] ar) {
staticEx3 ex = new staticEx3();
ex.makeStaticBlockObject();
// Start creating first StaticBlock Object
// First static block
// Second static block
// This is StaticBlock Constructor
// Complete createing first StaticBlock Object
// ===========================================
// Start creating second StaticBlock Object
// This is StaticBlock Constructor
// Complete createing second StaticBlock Object
// ===========================================
// ex1.name: Rengar
// ex2.name: Rengar
// ex1.name: Jax
// ex2.name: Jax
// staticBlock.name: Jax
}
public void makeStaticBlockObject() {
System.out.println("Start creating first StaticBlock Object");
staticBlock ex1 = new staticBlock();
System.out.println("Complete createing first StaticBlock Object");
System.out.println("===========================================");
System.out.println("Start creating second StaticBlock Object");
staticBlock ex2 = new staticBlock();
System.out.println("Complete createing second StaticBlock Object");
System.out.println("===========================================");
System.out.println("ex1.name: " + ex1.name);
System.out.println("ex2.name: " + ex2.name);
staticBlock.name = "Jax";
System.out.println("ex1.name: " + ex1.name);
System.out.println("ex2.name: " + ex2.name);
System.out.println("staticBlock.name: " + staticBlock.getData());
}
}
객체는 여러개를 생성하지만, 한번만 호출되어야하는 코드가 있다면
static 블록을 사용하면 됩니다.
static블록은 첫 객체가 생성될 때, 생성자보다 전에 실행됩니다.
그리고 그 이후에는 호출할 수 없습니다.
위의 코드를 보면 ex1 객체를 생성할 때 두개의 static블록이 실행되었고,
ex2 객체를 생설할 때는 실행되지 않았습니다.
static블록은 클래스 안에, 메소드 밖에 선언되어야 합니다.
그리고 static 블록 안에서는 static한 것들만 호출할 수 있습니다.
위 코드에서도 static 블록안에 사용된 name변수는 static입니다.
name이 static이기 때문에 staticBLock.name = “jax” 로 하자
ex1, ex2의 name이 모두 “Jax”로 바뀐 걸 볼 수 있습니다.