Java에서는 다음과 같은 차이점이 있습니다.
private final static int NUMBER = 10;
과
private final int NUMBER = 10;
및는 둘 다 private
이며 final
, 차이점은 static
속성입니다.
더 나은 게 뭐야? 그리고 왜?
답변
일반적으로 static
” 유형 의 인스턴스 가 아닌 유형 자체 와 관련됨”을 의미 합니다.
즉, 유형의 인스턴스를 만들지 않고도 정적 변수를 참조 할 수 있으며 변수를 참조하는 코드는 정확히 동일한 데이터를 참조합니다. 이것을 인스턴스 변수와 비교하십시오.이 경우 클래스의 인스턴스마다 하나의 독립 버전의 변수가 있습니다. 예를 들어 :
Test x = new Test();
Test y = new Test();
x.instanceVariable = 10;
y.instanceVariable = 20;
System.out.println(x.instanceVariable);
10 밖으로 인쇄 : y.instanceVariable
와는 x.instanceVariable
별개로 인해 x
및 y
다른 개체를 참조하십시오.
당신은 할 수 는 그렇게 나쁜 생각하지만, 참고 문헌을 통해 정적 멤버를 참조하십시오. 우리가 한 경우 :
Test x = new Test();
Test y = new Test();
x.staticVariable = 10;
y.staticVariable = 20;
System.out.println(x.staticVariable);
그러면 20이 출력됩니다-인스턴스 당 하나가 아닌 하나의 변수 만 있습니다. 이것을 다음과 같이 작성하는 것이 더 명확했을 것입니다.
Test x = new Test();
Test y = new Test();
Test.staticVariable = 10;
Test.staticVariable = 20;
System.out.println(Test.staticVariable);
그것은 행동을 훨씬 더 분명하게 만듭니다. 최신 IDE는 일반적으로 두 번째 목록을 세 번째 목록으로 변경하도록 제안합니다.
각 인스턴스마다 고유 NUMBER
하지만 항상 동일한 값 을 갖기 때문에 다음과 같이 값을 초기화하는 인라인 선언을 가질 이유가 없습니다 (불변이고 리터럴로 초기화 됨). 이것은 final static
모든 인스턴스에 대해 하나의 변수 만 갖는 것과 같습니다 .
private final int NUMBER = 10;
따라서 변경할 수없는 경우 인스턴스 당 하나의 사본이있는 지점이 없습니다.
그러나 다음과 같이 생성자에서 초기화되면 의미가 있습니다.
// No initialization when is declared
private final int number;
public MyClass(int n) {
// The variable can be assigned in the constructor, but then
// not modified later.
number = n;
}
이제의 각 인스턴스에 대해 MyClass
다르지만 변경할 수없는 값을 가질 수 있습니다 number
.
답변
에 대한 최종 초기화 할 때, 그것은 런타임에 다른 값을 할당 할 수 있습니다. 예를 들어
Class Test{
public final int a;
}
Test t1 = new Test();
t1.a = 10;
Test t2 = new Test();
t2.a = 20; //fixed
따라서 각 인스턴스의 필드 값이 다릅니다 습니다 .
들어 정적 최종 , 모든 인스턴스는 동일한 가치를 공유하고, 처음으로 초기화 한 후 변경할 수 없습니다.
Class TestStatic{
public static final int a;
}
TestStatic t1 = new TestStatic();
t1.a = 10;
TestStatic t2 = new TestStatic();
t1.a = 20; // ERROR, CAN'T BE ALTERED AFTER THE FIRST INITIALIZATION.
답변
static
변수 응용 프로그램의 전체 수명 동안 메모리에 숙박, 그리고 클래스 로딩시에 초기화됩니다. 않은 static
변수는 컨스마다 초기화되는 new
개체. 일반적으로 사용하는 것이 좋습니다 :
private static final int NUMBER = 10;
왜? 이를 통해 인스턴스 당 메모리 사용량이 줄어 듭니다. 캐시 적중에도 유리합니다. 그리고 그것은 의미 static
가 있습니다. 특정 유형 (일명 class
) 의 모든 인스턴스 (일명 객체)에서 공유되는 것들에 사용해야합니다 .
답변
정적은 “클래스와 연관된”을 의미합니다. 그렇지 않으면 변수가 클래스의 각 인스턴스와 연결됩니다. 정적이라면 메모리에 하나만 있다는 것을 의미합니다. 그렇지 않은 경우 생성 한 각 인스턴스마다 하나씩 있습니다. static은 클래스가로드되는 동안 변수가 메모리에 남아 있음을 의미합니다. 그것 없이는, 인스턴스가있을 때 변수를 gc’d 할 수 있습니다.
답변
답을 읽으면 실제로 진정한 요점을 찾지 못했습니다. 내 2 센트는 다음과 같습니다.
public class ConstTest
{
private final int value = 10;
private static final int valueStatic = 20;
private final File valueObject = new File("");
private static final File valueObjectStatic = new File("");
public void printAddresses() {
System.out.println("final int address " +
ObjectUtils.identityToString(value));
System.out.println("final static int address " +
ObjectUtils.identityToString(valueStatic));
System.out.println("final file address " +
ObjectUtils.identityToString(valueObject));
System.out.println("final static file address " +
ObjectUtils.identityToString(valueObjectStatic));
}
public static void main(final String args[]) {
final ConstTest firstObj = new ConstTest();
final ConstTest sndObj = new ConstTest();
firstObj.printAdresses();
sndObj.printAdresses();
}
}
첫 번째 객체에 대한 결과 :
final int address java.lang.Integer@6d9efb05
final static int address java.lang.Integer@60723d7c
final file address java.io.File@6c22c95b
final static file address java.io.File@5fd1acd3
두 번째 개체에 대한 결과 :
final int address java.lang.Integer@6d9efb05
final static int address java.lang.Integer@60723d7c
final file address java.io.File@3ea981ca
final static file address java.io.File@5fd1acd3
결론 :
자바가 원시 유형과 다른 유형을 구별한다고 생각했습니다. Java의 기본 유형은 문자열 리터럴 (새 문자열 오브젝트가 아님)과 동일하게 항상 “캐시”되므로 정적 멤버와 비 정적 멤버간에 차이가 없습니다.
그러나 비 정적 멤버가 기본 유형의 인스턴스가 아닌 경우 비 정적 멤버에 대한 메모리 복제가 있습니다.
Java가 두 개의 int 변수에 동일한 주소를 제공하므로 valueStatic의 값을 10으로 변경하면 더 나아가게됩니다.
답변
다른 답변은 일반적으로 비 정적 상수를 사용할 이유가 없다는 것을 분명히하는 것처럼 보이지만 상수 변수에 다른 값을 가진 다양한 인스턴스를 가질 수 있음을 지적하는 사람을 찾을 수 없었습니다.
다음 예제를 고려하십시오.
public class TestClass {
private final static double NUMBER = Math.random();
public TestClass () {
System.out.println(NUMBER);
}
}
TestClass의 3 개의 인스턴스를 생성하면 하나의 값만 생성되어 정적 상수에 저장되므로 동일한 임의의 값을 세 번 인쇄합니다.
그러나 대신 다음 예제를 시도하면
public class TestClass {
private final double NUMBER = Math.random();
public TestClass () {
System.out.println(NUMBER);
}
}
TestClass의 3 개의 인스턴스를 만들면 각 인스턴스마다 임의로 생성 된 상수 값이 있기 때문에 3 개의 다른 임의의 값이 인쇄됩니다.
다른 인스턴스에서 다른 상수 값을 갖는 것이 실제로 유용한 상황은 생각할 수 없지만 정적과 비 정적 결승 사이에 명확한 차이가 있음을 지적하는 데 도움이되기를 바랍니다.
답변
Jon이 말했듯이 클래스 변수라고도하는 정적 변수는 클래스의 인스턴스에 존재하는 변수입니다.
public class StaticVariable
{
static int noOfInstances;
StaticVariable()
{
noOfInstances++;
}
public static void main(String[] args)
{
StaticVariable sv1 = new StaticVariable();
System.out.println("No. of instances for sv1 : " + sv1.noOfInstances);
StaticVariable sv2 = new StaticVariable();
System.out.println("No. of instances for sv1 : " + sv1.noOfInstances);
System.out.println("No. of instances for st2 : " + sv2.noOfInstances);
StaticVariable sv3 = new StaticVariable();
System.out.println("No. of instances for sv1 : " + sv1.noOfInstances);
System.out.println("No. of instances for sv2 : " + sv2.noOfInstances);
System.out.println("No. of instances for sv3 : " + sv3.noOfInstances);
}
}
프로그램 출력은 다음과 같습니다.
이 예제에서 볼 수 있듯이 각 객체에는 고유 한 클래스 변수 사본이 있습니다.
C:\java>java StaticVariable
No. of instances for sv1 : 1
No. of instances for sv1 : 2
No. of instances for st2 : 2
No. of instances for sv1 : 3
No. of instances for sv2 : 3
No. of instances for sv3 : 3