문제

나는 내 직장에서 Java 코드를 발견하게된다. 시나리오는 다음과 같습니다. 2 개의 클래스가 있습니다. ClassA 그리고 ClassB.

ClassA 그 안에는 4 개의 공개 정적 최종 문자열 값을 제외하고는 없습니다. 그 목적은 그와 같은 값을 사용하는 것입니다 ClassA.variable (왜 내 코드가 아닌지 묻지 마십시오).

ClassB 수입 ClassA. 문자열 값을 편집했습니다 ClassA 그리고 그것을 편집했습니다. 내가 달렸을 때 ClassB 새로운 값이 아닌 이전 값을 사용하는 것을 볼 수있었습니다. 나는 다시 컴파일해야했다 ClassB 새로운 값을 사용하게합니다 ClassA! (수입하는 다른 클래스를 다시 컴파일해야했습니다 ClassA!)

이것은 JDK 1.6 때문입니까, 아니면 이전에 다시 컴파일하는 것을 알고 있었을 것입니다. ClassB 또한! 나를 깨달으십시오. :)

도움이 되었습니까?

해결책

값의 값이 있다면 final 클래스의 변수 ClassA 컴파일 타임 상수가되면 컴파일러가이를 사용하여 클래스에 상환했을 수 있습니다. ClassA 런타임 참조를 생성하는 대신. 나는 이것이 당신이 설명한 경우에 일어난 일이라고 생각합니다.

예시:

public class Flags {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

public class Consumer {
    public static void main(String[] args) {
         System.out.println(Flags.FOO);
    }
}

이 예에서 컴파일러는 FOO 생성 된 코드로 Consumer 동등한 런타임 참조를 생성하는 대신. 값의 경우 FOO 나중에 변경하면 다시 컴파일해야합니다 Consumer 새 값을 사용하기 위해.

이것은 최적화로, 컴파일 된 프로그램의 효율성과 속도와 관련하여 몇 가지 장점이 있습니다. 예를 들어, 값을 인화하는 값은 예를 들어 다음과 같은 표현식에서 추가 최적화를 가능하게 할 수 있습니다.

int x = Flags.FOO * 10;

이 예에서 값을 인화하면 (여기 : 1), 컴파일러가 곱셈이 차이가없고, alltogether를 생략 할 수 있음을 알 수 있습니다.

다른 팁

이진 호환 문제입니다. 상수 필드에 대한 참조는 컴파일 시간에 해결됩니다. 당신이보고있는 행동은 옳습니다. 클래스 A의 값을 변경하면 클라이언트 (클래스 B)를 다시 컴파일해야합니다. 이러한 문제를 피하려면 Java 릴리스 5.0에 도입 된 열거 유형을 사용하여 상수를 추가하는 것을 고려하십시오.

왜 수업을 개별적으로 컴파일하려고합니까?

Maven 또는 Ant와 같은 빌드 시스템을 사용하거나 IDE가 수행하도록하십시오.

해야 할 유일한 안전한 일은 자바 클래스에 의존하는 모든 Java를 다시 컴파일하는 것입니다.

스위치에서 값을 사용하지 않는 경우 대신이 작업을 수행 할 수 있습니다.

public class A
{
    public static final int FOO;
    public static final String BAR;

    static
    {
        FOO = 42;
        BAR = "Hello, World!";
    }
}

컴파일러는 더 이상 사용중인 다른 클래스의 값을 하드 코드하지 않습니다.

classa가 다음과 같이 보인다고 가정합니다.

public class ClassA {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

다시 컴파일하면 ClassB는 이전 값을 계속 사용합니다. 컴파일러에 의존 할 수 있다고 생각하지만 이것이 일반적인 동작이라고 생각합니다. Classa의 상수가 변경 될 때마다 ClassB를 다시 컴파일하지 않으려면 다음과 같은 작업을 수행해야합니다.

public class ClassA {
    public static final int FOO = CONST(1);
    public static final int BAR = CONST(2);

    public static int CONST(int i) { return i; }
}

Becuase 이제 Javac은 상수를 인화하지 않으려 고합니다. 대신 Classa의 정적 이니셜 라이저가 실행되면 const (int) 메소드를 호출합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top