2009-12-18 3 views
62

Java로 프로그램하기 시작했고 C++ #define에 해당하는지 궁금합니다.#define in Java

구글의 빠른 검색은하지 않지만, 비슷한 자바에 을있는 경우 누군가가 나에게 말할 수 있다고? 내 코드를 더 읽기 쉽게하려고합니다.

예를 들어 myArray[0] 대신 myArray[PROTEINS]을 쓸 수 있기를 바랍니다.

+8

현대적인 C++에서는 #define이 아닌 typed constant를 사용해야합니다. –

+2

예, #define은 C 스타일입니다. C++에서는 대신 const를 사용하십시오. Scott Meyers "Effective C++"book, Item 1을 참조하십시오. – Jabba

답변

84

아니오, 프리 D 파일러가 없기 때.입니다.

class MyClass 
{ 
    private static final int PROTEINS = 0; 

    ... 

    MyArray[] foo = new MyArray[PROTEINS]; 

} 

는 컴파일러는 PROTEINS은, 지금까지 변경할 수 없다는 통지 등 것이다 것 : 다음과 같이 경우에 당신이 같은 일을 달성 할 수 있도록

그러나, 핫스팟은 어디 가능한 최적화에 매우 놀라 울 정도로 좋다 당신이 원하는 것을 어느 정도 인라인 할 수 있습니다.

상수에 대한 액세스 한정자는 여기에서 중요하지 않으므로 여러 클래스에 동일한 상수를 다시 사용하려면 private 대신 public 또는 protected이 될 수 있습니다.

+13

이 질문에 대한 대답은되지만 몇 가지 용어를 오용합니다. 인라인은 런타임에 JIT 컴파일러가 메서드가 충분히 간단하고 재정의되지 않는다는 것을 알 때 수행됩니다 (모든 규칙을 알지 못하고 버전이 변경 될 수 있음). 프리미티브 또는 String 타입의 'static final'은 JIT가 아닌 Java 컴파일러 사양에 의해 상수로 정의됩니다. JIT의 의미에서 "인라인 된"것이 아니라 실제로 #define이 C처럼 코드의 해당 부분에 직접 컴파일됩니다. –

5
static final int PROTEINS = 1 
... 
myArray[PROTEINS] 

보통 "상수"를 클래스 자체에 넣습니다. 그리고 컴파일러가 참조를 최적화 할 수 있다는 점에 유의하십시오. 따라서 모든 사용하는 클래스를 다시 컴파일하지 않는 한 컴파일러를 변경하지 마십시오.

class Foo { 
    public static final int SIZE = 5; 

    public static int[] arr = new int[SIZE]; 
} 
class Bar { 
    int last = arr[Foo.SIZE - 1]; 
} 

주기 편집 ... SIZE=4. 컴파일러가 마지막 컴파일주기에 방금 "4"를 작성했기 때문에 Bar도 컴파일하십시오!

4

자바는 범용 define 처리기 지시문이 없습니다. 상수의 경우

, (값이 일정한 컴파일 시간 인 경우)

private static final int PROTEINS = 100; 

이러한 선언은 컴파일러에 의해 인라인 될 것 에서처럼, static finals로 선언하는 것이 좋습니다.

공공 정적 최종 상수 필드는 공용 인터페이스의 일부이며 (컴파일러를 인라인으로) 그 값이 변경되지해야한다고도 있습니다. 값을 변경하면 해당 상수 필드를 참조한 모든 소스를 다시 컴파일해야합니다.

+0

음, * private *'static finalals '은 실제로 * public * 인터페이스의 일부가 아닙니다. :)'public static finalals'의 경우 이것은 사실입니다. – Bombe

+0

@ 엄마, 맞습니다. 처음에는 공개적으로 썼지 만 대답을 업데이트하지 않고 변경되었습니다. – notnoop

34

코멘트 공간이 너무 작은, 그래서 여기 static final의 사용에 당신을 위해 좀 더 정보입니다. 내가 Andrzej's answer에 대한 내 의견에서 말했듯이 프리미티브와 String 만 리터럴로 코드에 직접 컴파일됩니다.이를 설명하기 위해, 다음과 같이 해보십시오

Int = 0 
Value = A 
을 :

public class DisplayValue { 
    private String value; 

    public DisplayValue(String value) { 
     this.value = value; 
    } 

    public String toString() { 
     return value; 
    } 
} 

public class Constants { 
    public static final int INT_VALUE = 0; 
    public static final DisplayValue VALUE = new DisplayValue("A"); 
} 

public class Test { 
    public static void main(String[] args) { 
     System.out.println("Int = " + Constants.INT_VALUE); 
     System.out.println("Value = " + Constants.VALUE); 
    } 
} 

인쇄 테스트를,이 컴파일 및 실행

있습니다 (별도의 파일에) 세 개의 클래스를 생성하여 동작에서 볼 수 있습니다

이제 Constants을 각각 다른 값으로 변경하고 클래스 Constants 만 컴파일하면됩니다. Test을 다시 실행하면 (클래스 파일을 다시 컴파일하지 않고) INT_VALUE의 이전 값은 인쇄되지만 VALUE은 인쇄되지 않습니다. Test.java 재 컴파일없이

public class Constants { 
    public static final int INT_VALUE = 2; 
    public static final DisplayValue VALUE = new DisplayValue("X"); 
} 

테스트 실행 : static final에 사용되는 다른 종류의 참조로서 유지하도록

Int = 0 
Value = X 

참고 예. C 유사

/C++ 일정한 문자 또는 하나가 if 내의 명령문의 바이트 코드를 제거하기 위해 컴파일러 발생할 정규 자바 if 상태에서 사용 false로 평가 프리미티브 static final 통해 정의 #if/#endif, 블록 (생성되지 않음).

private static final boolean DEBUG = false; 

if (DEBUG) { 
    ...code here... 
} 

"... 여기 코드 ..."의 코드는 바이트 코드로 컴파일되지 않습니다. 하지만 DEBUGtrue으로 변경하면됩니다.

+1

분명히 노력을 위해 +1! –

+0

단지 자바가'enum's에 대해서 똑같이하지 않는다고 덧붙이고 싶습니다. –

0

가장 간단한 답변은 입니다. "사전 컴파일러가 없기 때문에 직접 가져올 방법이 없습니다" 하지만 혼자서 할 수 있습니다. 클래스를 사용하고 최종으로 변수를 정의하면 프로그램 전체에서 상수로 간주 될 수 있습니다.
최종 변수와 변수를 공용 또는 개인이 아닌 개인으로 사용하는 것을 잊지 마세요. 그렇지 않으면 액세스 할 수 없습니다. 그 클래스 외부에서

0

대부분 읽을 수있는 해결책은 Static Import를 사용하고 있습니다. 그러면 이 아닌AnotherClass.constant을 사용해야합니다.

상수가 public static 인 클래스를 작성하십시오.

package ConstantPackage; 

public class Constant { 
    public static int PROTEINS = 1; 
} 

그럼 그냥 사용 정적 가져 오기 당신이 상수를 필요.

import static ConstantPackage.Constant.PROTEINS; 

public class StaticImportDemo { 

    public static void main(String[]args) { 

     int[] myArray = new int[5]; 
     myArray[PROTEINS] = 0; 

    } 
} 

정적 가져 오기에 대해 자세히 알아 보려면 this stack overflow question을 참조하십시오.

2

#define, #ifdef, #ifndef 및 많은 다른 지시어를 제공하는 preprocessor for Java이 있습니다. 예를 들어 PostgresJDBC 팀은 다른 케이스의 소스를 생성하고 코드를 복제하지 않기 위해이를 사용합니다.