상수

"아미고, Java에서 모든 변수를 변경할 수 있는 것은 아니라는 사실을 알고 계셨습니까?"

"어때요, 김씨? 사실 '변수'라는 단어 자체가 변화를 말하죠."

"그 점에 대해서는 의심의 여지가 없습니다. 다른 많은 프로그래밍 언어와 마찬가지로 Java에도 상수 , 즉 값을 변경할 수 없는 변수가 있습니다 . 그리고 '상수'라는 단어 자체가 불변성을 나타냅니다."

"그리고 그것들은 무엇입니까?"

"보통, 그것들은 한 해의 달의 숫자나 일수와 같은 일종의 기본적인 것에 사용됩니다 Pi. 즉, 원칙적으로 프로그래머는 어떤 변수를 상수로 만들 수 있습니다. 그래서 필요하다."

"이름, 자동차 색상 또는 요일 이름 같은 것을 의미합니까?"

"당신은 올바른 생각을 가지고 있습니다. 변경해서는 안되는 모든 것."

"그리고 이러한 상수는 Java에서 어떻게 생겼습니까?"

"Java에는 특수 키워드가 있습니다: final. 불변 변수를 생성하는 것은 일반 변수를 생성하는 것과 같습니다. 유일한 차이점은 변수 유형 앞에 final다음과 같이 단어를 작성해야 한다는 것입니다.

final Type name = value;

"상수를 만든 다음 다른 값을 할당하려고 하면 어떻게 됩니까?"

"그게 올바른 질문입니다! 그리고 정답은 이것입니다. 변수에 다른 값을 할당하려고 하면 final프로그램이 컴파일되지 않습니다."

"변수를 선언했지만 final값을 할당하지 않으면 어떻게 될까요?"

"이렇게 하는 것은 의미가 없으므로 Java에서도 허용되지 않습니다. 변수 final는 선언될 때 초기화되어야 합니다. 즉, 변수에 값을 할당해야 합니다. 이 규칙에는 한 가지 예외가 있습니다. 생성자에 대한 정적 클래스 변수 그러나 나중에 이에 대해 배우게 됩니다.

"즉, 모든 것이 상수인 것은 아닙니다 . 키워드 수를 줄이기 위해 Java 개발자는 상수를 선언하는 것 이상으로 final단어를 사용합니다 . 메소드 및 클래스에도 적용할 수 있습니다 . 상속할 수 없는 것으로 선언되었습니다 ."finalfinalfinalfinal

"어... 오버라이드? 상속? 지금 무슨 언어로 말하는 거야?"

"객체 지향 프로그래밍의 언어입니다. 곧 알게 될 것입니다. 그때까지는 아름다운 용어를 즐기십시오."

"알겠습니다. final변수, 클래스 및 메소드 앞에 놓을 수 있으며 이 키워드는 어떤 의미에서 그것들을 불변으로 만듭니다."

"예. 또한 final지역 변수, 메서드 매개 변수, 클래스 필드 및 정적 클래스 변수와 같은 모든 변수 앞에 수정자를 추가할 수 있습니다.

"여기에 기억해야 할 중요한 사항이 있습니다. final변수 이름은 해당 변수 에 대한 변경 사항에 대한 보호일 뿐입니다 . 변수가 객체에 대한 참조를 저장하는 경우 객체는 여전히 변경될 수 있습니다."

"잘 이해가 안 돼요."

"당신은 정말 곧 이해하게 될 것입니다. 다음은 예입니다.

final int[] data = {1, 2, 3, 4, 5, 6};

data = {6, 7, 8, 9};

data[0] = 0;
data[1] = 0;
data[2] = 0;
배열을 만듭니다.

이것은 허용되지 않습니다. 변수 data가 로 선언됩니다 final.

그러나 당신은 이것을 할 수 있습니다.
그리고 이것도.

"알았어. 까다롭군."

전역 상수

"전역 상수가 무엇이라고 생각하십니까?"

"전역 상수는 아마도 전역 변수와 같을 것입니다. 상수만 있습니까?"

"정확합니다. 프로그램에서 전역 상수를 선언해야 하는 경우 정적 클래스 변수를public 생성하고 및 로 만드십시오 final. 이러한 변수의 이름에는 특별한 스타일이 있습니다. 별도의 단어.

예:

class Solution
{
   public static final String SOURCE_ROOT = "c:\\projects\\my\\";
   public static final int DISPLAY_WIDTH = 1024;
   public static final int DISPLAY_HEIGHT = 768;
}

변수 섀도잉

"앞서 말했듯이 단일 메서드에서 동일한 이름을 가진 여러 지역 변수를 만들 수 없습니다. 다른 메서드에서는 가능합니다."

"나도 알아!"

"하지만 아마도 당신이 모르는 것은 클래스의 변수와 메서드의 지역 변수가 같은 이름을 가질 수 있다는 것입니다.

예:

암호 변수 가시성
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     sum = sum + data;
     int sum = data * 2;
     count++;
   }
}

count, sum
count, sum
count, sum
count, sum
count, sum
count, sum, data
count, sum, data
count, sum, data
count, sum, data
count, sum

"메서드에서 add우리는 이라는 지역 변수를 선언했습니다 sum. 메서드가 끝날 때까지 인스턴스 변수를 가리거나 가 립니다 .sum "

"흠... 어떤 의미에서는 이것이 예상되는 동작이라고 말할 수 있습니다."

this"그러나 그것이 이야기의 끝은 아닙니다. 인스턴스 변수가 지역 변수에 의해 가려지는 경우 메서드 내에서 인스턴스 변수를 참조할 수 있는 방법이 여전히 있다는 것이 밝혀졌습니다. 이름 앞에 키워드를 작성하여 이를 수행합니다. :

this.name

"이름 충돌이 성공적으로 해결된 예는 다음과 같습니다.

암호 변수 가시성
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     this.sum = this.sum + data;
     count++;
   }
}

this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum, data
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum

count및 변수 는 키워드 sum가 있거나 없는 모든 곳에서 사용할 수 있습니다 this. 로컬 변수가 인스턴스 변수를 sum가리는 줄에서 인스턴스 변수는 키워드를 통해서만 액세스할 수 있습니다 .sumsumthis

"분명히, 나는 이것을 연습해야 할 것입니다."

"당신은 관리 할 것입니다."

"(비정적) 인스턴스 변수가 아닌 정적 클래스 변수가 가려지면 어떻게 됩니까? 를 통해 액세스할 수 없습니까 this?"

"맞습니다. this 키워드는 작동하지 않습니다. 클래스 이름을 통해 참조해야 합니다.

ClassName.name

예:

암호 변수 가시성
public class Solution
{
   public static int count = 0;
   public static int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     Solution.sum = Solution.sum + data;
     count++;
   }
}

Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum, data
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum

"주의: 클래스 이름을 접두사로 사용하거나 사용하지 않고 어디에서나 정적 변수 count에 액세스할 수 있습니다. 로컬 변수가 인스턴스 변수를 가리는 행에서 클래스 변수 에 대한 액세스는 접두사로 사용할 때만 가능합니다 .sumSolutionsumsumsumSolution

for루프 내부의 변수

"그리고 작지만 흥미로운 사실이 하나 더 있습니다. 변수가 특별한 방식으로 선언되는 곳도 있습니다. 루프 내부에 대해 이야기하고 있습니다 for. " 일반적으로 루프 에는 괄호 안에 변수가 for있습니다 . counter그리고 이 변수의 가시성은 어떻게 될까요? 결국, 그것은 루프 본문에 있지 않습니다. 전체 방법입니까? 아님?"

for"나는 이미 이것에 대해 뭔가를 들었습니다. 내가 이해하는 한, 루프 의 헤더에 선언된 변수는 루프의 본문루프 의 헤더for 에서만 볼 수 있습니다 ."

"잘했어, 아미고. 그래도 이 자료를 보강하기 위한 예를 살펴보자.

암호 변수 가시성
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a

"그래서 당신은 내 코드에서 같은 이름의 카운터 변수를 사용하여 여러 루프를 차례로 작성할 수 있고 문제가 없을 것이라고 말하는 건가요?"

"문제 없을 겁니다. 여기 보세요.

암호 변수 가시성
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   for (int i = 0; i < 10; i--)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a, i
a, i
a, i
a
a
a