자바 수정자. 접근 수정자

먼저 접근 한정자를 살펴보자. 그 중 네 가지만 있습니다:

  • 사적인클래스 멤버는 클래스 내에서만 접근 가능
  • package-private 또는 default (기본값)클래스 멤버는 패키지 내부에 표시됩니다.
  • 보호됨클래스 멤버는 패키지 내부 및 하위 클래스에서 사용할 수 있습니다.
  • 공공의수업 구성원은 누구나 사용할 수 있습니다.

상속 중에 더 많은 가시성을 갖도록 액세스 수정자를 변경할 수 있습니다.

생성자, 메서드 및 필드에는 모든 액세스 수정자가 있을 수 있지만 클래스와 해당 블록을 사용하면 모든 것이 그렇게 간단하지 않습니다. 클래스는 공개 또는 기본 클래스일 수 있으며, 하나의 파일에는 공개 클래스가 하나만 있을 수 있습니다. 블록에는 수정자가 하나만 있을 수 있습니다(기본값).

정적, 추상 및 최종 수정자

공전

  • 내부 클래스, 메소드, 변수 및 논리 블록에 적용됩니다.
  • 클래스가 로드될 때 정적 변수가 초기화됩니다.
  • 정적 변수는 모든 클래스 객체에 대해 동일합니다(동일한 참조).
  • 정적 메소드는 정적 변수에만 접근할 수 있습니다.
  • 정적 메소드 및 변수는 클래스 이름을 통해 액세스할 수 있습니다.
  • 클래스 로딩 중에 정적 블록이 실행됩니다.
  • 비정적 메서드는 정적 메서드로 재정의할 수 없습니다.
  • 지역 변수는 정적으로 선언할 수 없습니다.
  • 추상 메서드는 정적일 수 없습니다.
  • 정적 필드는 직렬화되지 않습니다(직렬화 가능 인터페이스를 구현하는 경우에만).
  • 정적 클래스 변수만 super(//parameter//) 또는 this(//parameter//)를 통해 호출되는 매개변수화된 생성자에 전달될 수 있습니다.

추상적인

  • 메서드 및 클래스에만 적용됩니다.
  • 추상 메서드에는 메서드 본문이 없습니다.
  • final의 반대입니다. final 클래스는 상속할 수 없으며 추상 클래스는 상속해야 합니다.
  • 다음과 같은 경우 클래스를 추상으로 선언해야 합니다.
  1. 적어도 하나의 추상 메서드를 포함합니다.
  2. 상속된 추상 메서드의 구현을 제공하지 않습니다.
  3. 구현이 선언된 인터페이스의 메소드 구현을 제공하지 않습니다.
  4. 클래스의 인스턴스 생성을 금지해야 합니다.

결정적인

  • 필드를 변경할 수 없으며 메서드가 재정의됩니다.
  • 클래스는 상속될 수 없습니다.
  • 이 수정자는 클래스, 메서드 및 변수(지역 변수도 포함)에만 적용됩니다.
  • final로 표시된 메서드 인수는 읽기 전용이므로 이를 변경하려고 하면 컴파일 오류가 발생합니다.
  • 최종 변수는 기본적으로 초기화되지 않습니다. 선언할 때나 생성자에서 명시적으로 값을 할당해야 하며, 그렇지 않으면 컴파일 오류가 발생합니다.
  • 최종 변수에 객체에 대한 참조가 포함되어 있으면 객체를 수정할 수 있지만 변수는 항상 동일한 객체를 참조합니다.
  • 이는 배열의 경우에도 마찬가지입니다. 배열은 객체이기 때문입니다. 배열은 변경될 수 있지만 변수는 항상 동일한 배열을 참조합니다.
  • 클래스가 최종 및 추상(상호 배타적)으로 선언되면 컴파일 오류가 발생합니다.
  • 최종 클래스는 상속될 수 없으므로 해당 메서드는 절대 재정의될 수 없습니다.
건설자정적이거나 추상적이거나 최종적일 수 없습니다.

한정자 strictfp, 일시적, 휘발성, 동기화됨, 기본

엄격한

  • 메서드 및 클래스에 적용됩니다.
  • IEEE 754 표준에 따라 부동 소수점 및 이중 숫자(부동 소수점)에 대한 연산을 제공합니다.

과도 현상

  • 클래스 수준 변수에만 적용됩니다(지역 변수는 임시로 선언할 수 없음).
  • 임시 변수는 최종 변수이거나 정적 변수가 아닐 수 있습니다.
  • 임시 변수는 직렬화되지 않습니다.

휘발성 물질

  • 변수에만 사용됩니다.
  • 정적 변수와 함께 사용할 수 있습니다.
  • 최종 변수와 함께 사용되지 않음 - 휘발성으로 선언되고 한 스레드에 의해 변경된 변수의 값은 다른 스레드에 대해 비동기적으로 변경됩니다.
  • 멀티스레드 애플리케이션에 사용됨

동기화됨

  • 메소드 또는 메소드의 일부에만 적용됩니다.
  • 다중 스레드 프로그램에서 중요한 코드 부분에 대한 액세스를 제어하는 ​​데 사용됩니다.

토종의

  • 메소드에만 사용됩니다.
  • 메소드가 다른 프로그래밍 언어로 작성되었음을 나타냅니다.
  • Java의 클래스는 성능을 향상하고 하드웨어에 대한 액세스를 향상하기 위해 다양한 기본 메소드를 사용합니다.
  • 네이티브 메소드에서 Java 객체를 전달/반환할 수 있습니다.
  • 메소드 시그니처는 ";"으로 끝나야 하며 중괄호를 사용하면 컴파일 오류가 발생합니다.

인터페이스의 기능

  • 메소드는 선언되지 않은 경우에도 항상 공개적이고 추상적입니다.
  • 메소드는 static, final, strictfp, Native, private, protected일 수 없습니다.
  • 변수는 선언되지 않은 경우에도 public static final입니다.
  • 변수는 strictfp, 기본, 개인용, 보호될 수 없습니다.
  • 다른 인터페이스를 확장할 수만 있고 인터페이스나 클래스를 구현할 수는 없습니다.

모든 수정자를 하나로 묶어 보겠습니다.

수업

내부 클래스

변하기 쉬운

방법

건설자

논리 블록

공공의

아니요

보호됨

아니요

(로컬 및 익명 클래스 제외)

아니요

기본

사적인

아니요

(로컬 및 익명 클래스 제외)

아니요

결정적인

예(지역 변수의 경우)

아니요

아니요

추상적인

예(익명 클래스 제외)

아니요

아니요

아니요

공전

아니요

(로컬 및 익명 클래스 제외)

아니요

토종의

아니요

아니요

아니요

아니요

아니요

과도 현상

아니요

아니요

아니요

아니요

아니요

동기화됨

아니요

아니요

아니요

아니요

예(방법의 일부로만)

휘발성 물질

아니요

아니요

아니요

아니요

아니요

엄격한

아니요

아니요

아니요

수정자 클래스
Modifier 클래스는 모든 수정자를 인코딩합니다.
유형 선언에 사용되는 형식
상수:
추상, 최종, 인터페이스, 기본,
개인, 보호, 공개, 정적,
엄격하고, 동기화되고, 일시적이며,
휘발성 물질.
각 상수는 다음 형식의 요청 메서드로 응답됩니다.
isMod(int modifier) ​​​​(여기서 Mod는 위의 것 중 하나입니다
특정 이름(예: isPublic),
수정자가 있으면 true를 반환합니다.
mod는 유형 선언에 있습니다.

예를 살펴보겠습니다. 있게 해주세요
필드 선언
공개 정적 최종 int s=10;
그런 다음 메서드에서 반환된 값
해당 객체의 getModifiers
클래스 필드는 다음과 같습니다
수정자.PUBLIC | 수정자.STATIC |
수정자.최종
strictfp 수정자가 나타납니다
상수 STRICT.
쿼리 메소드는 다음에서 사용할 수 있습니다.
다음 양식

Modifier.isPrivate(field.getModifiers());
이는 다음 조건과 동일합니다.
(field.getModifiers()&Modifier.PRIVATE)!=0
클래스 필드
Field 클래스는 메소드를 구현합니다.
귀하가 다음에 관한 정보를 요청할 수 있도록 허용합니다.
필드 유형을 읽고 설정할 수 있습니다.
의미.
Field 클래스의 몇 가지 메서드를 살펴보겠습니다.
1. getType() - 클래스 객체를 반환합니다.
현재 필드의 유형에 해당하는 클래스입니다.
예를 들어 int 유형의 필드에 대해 다음을 얻습니다.
int.class.

2. 메소드 설정 및 가져오기 - 읽을 수 있도록 허용
필드의 현재 값을 확인하고 새 값을 설정합니다.
예를 살펴보겠습니다:
공개 정적 무효 printField(객체 o,
문자열 이름) 던지기
NoSuchFieldException,
불법접근예외(
필드 필드 = o.getClass().getField(이름);
짧은 값 = (짧은) field.get(o);
System.out.println(값);
}
저것들. get 메소드는 다음 값을 반환합니다.
해당 필드 또는 개체를 나타냅니다.
쉘 클래스.
set 메소드를 사용하는 예는 다음과 같습니다:

public static void setField(객체 o, 문자열 이름,
짧은 nv) 던지기
NoSuchFieldException,
불법접근예외(
필드 field = o.getClass().getField(name) ;
field.set(o,new Short(nv));
}
주어진 객체의 필드에 nv를 저장하려면
래퍼 클래스를 사용해야 합니다.
형태의 메소드도 있습니다.
getPrimitiveType(예: getInt) 및
setPrimitiveType. 이러한 방법은 다음과 같습니다.
클래스의 필드를 변경하는 데 사용합니다.
원시적인 유형을 가지고 있습니다. 예를 들어,
field.setShort(o,nv);

메소드 클래스
메소드 클래스는 - 수신을 허용한다는 것을 의미합니다.
에 관한 완전한 정보
특정 클래스의 메소드 선언,
필요한 경우 다음 메서드를 호출하세요.
주어진 객체의 맥락.
Method 클래스의 메소드를 살펴보겠습니다.
1. 공용 클래스 getReturnType() - 반환
유형에 대응하는 Class 객체
현재 메서드에서 반환된 값입니다.
반환 유형 대신에
메소드 선언은 서비스를 지정합니다
void라는 단어가 있으면 해당 메서드가 반환됩니다.
void.class 객체.

2. 공용 클래스 getParameterTypes() - 반환

광고에 지정된 매개변수
현재 방법. 객체는 배열에 입력됩니다.
매개변수가 나열된 순서대로
메소드 선언. 메소드가 없으면
매개변수를 사용하면 빈 배열이 반환됩니다.
3. 공용 클래스 getExceptionTypes() - 반환
유형에 해당하는 Class 객체의 배열
문장에 명시된 예외
현재 메소드의 선언을 던집니다. 사물
배열에 순서대로 입력됩니다.
예외 유형의 이름은 다음에 나열되어 있습니다.
메소드 선언.

4. 공용 객체 호출(Object onThis, Object args)
IllegalAccessException이 발생합니다.
IllegalArgumentException,
InvocationTargetException
현재 객체에 정의된 메서드를 호출합니다.
작업이 포함된 onThis 개체의 컨텍스트에서 메서드
args 배열에 의해 전달된 인수의 값.
비정적 메서드의 경우 구현 선택
실제 유형에 따라 수행
onThis 매개변수로 정의된 개체입니다. 을 위한
정적 메소드 onThis는 허용되지 않습니다.
주의를 기울이고 null일 수 있습니다.
args 배열의 길이는 숫자와 일치해야 합니다.
메소드 선언의 매개변수 및 배열 요소의 객체 유형은 할당을 허용해야 합니다.
해당 유형의 메소드 매개변수 - in
그렇지 않으면 예외가 발생합니다
IIlegalArgumentException.

10.

객체의 일부로 정의된 경우
on이 매개변수, 유형 없음, 멤버
이것이 현재의 방법이고,
예외가 발생합니다
IllegalArgumentException.
onThis가 null이고 메소드가 null이 아닌 경우
정적, 유형 예외가 발생합니다.
NullPointerException.
호출된 메소드가 실행되는 경우
비정상적으로 종료되어 버려집니다.
InvocationTargetException 유형의 예외입니다.

11.

예를 살펴보겠습니다. 수단으로 전화하자
리플렉션 메소드 return str.indexOf(".", 8)
그럼 우리는
노력하다 (
클래스 strClass = str.getClass();
메소드 indexM = strClass.getMethod("indexOf",
new Class(string.class, int.class));
객체 결과 = indexM.invoke(str, 새 객체(
".", new 정수(8)));
return ((Integer) 결과).intValue();
}
catch (NoSuchMethodException e) ( ….. )
잡기 (invocationTargetException e) (……..)
catch (illegalAccessException e) (……)

12.

생성자 클래스
새 인스턴스(객체)를 생성하려면
유형 방법을 사용할 수 있습니다
클래스 객체의 newInstance,
이 유형에 해당합니다.
이 메서드는 인수 없이 생성자를 호출합니다.
유형에 속하며 참조를 반환합니다.
Object 클래스의 새로 생성된 객체에,
명시적으로 다음으로 변환되어야 합니다.
필수 유형.
예를 살펴보겠습니다.

13.

static double testData = ( 0.3,1.3e-2, 7.9, 3.17 );

노력하다 (
for(int 인수 = 0; 인수< args.length; arg++){
문자열 이름 = args;
클래스 classFor = Class.forName(이름);
Sort이중 정렬기 =
(SortDouble)classFor.newInstance();
SortMetrics 지표 = sorter.sort(testData);
System.out.println(이름 + ": " + 메트릭);
for(int i =0; i< testData.length; i++)
System.out.println(“ " + testData[i]); ) )
catch(예외 e) ( System.err.println(e); ) )

14.

잘못된 경우 newInstance 메서드
응용 프로그램은 큰 크기를 버릴 수 있습니다
다양한 예외 객체의 수
유형.
InstantiationException - 클래스, 객체인 경우
창조되어야만 하는 것은 소유하지 않는다
인수가 없는 생성자 또는
추상적으로 정의되거나
실제로는 인터페이스입니다
또는 생성 절차를 수행하는 중
다른 이유로 개체가 중단되었습니다.
원인.
IllegalAccessException - 클래스가 다음 중 하나인 경우
인수가 없는 생성자를 사용할 수 없습니다.

15.

SecurityException - 정책이 유효한 경우
보안으로 인해 새 개체 생성이 금지됩니다.
ExceptionInInitializerError – 다음 경우에 발생합니다.
클래스 초기화.
Constructor 클래스는 다른 메서드도 정의합니다.
공용 클래스 getParameterTypes()

매개변수 유형에 해당하는
현재 생성자의 선언에 지정됩니다.
공용 클래스 getExceptionTypes()
클래스 객체의 배열을 반환합니다.
예외 유형에 해당하는
선언의 throws 절에 지정됨
현재 생성자.

16.

공개 객체 newInstance(객체 인수)
InstantiationException이 발생합니다.
불법접근예외,
IllegalArgumentException,
InvocationTargetException
현재 생성자가 나타내는 생성자를 사용합니다.
생성하고 초기화할 생성자 객체
생성자가 있는 클래스의 새 인스턴스
선언되어 지정된 인수를 전달합니다.
새로 생성된 링크에 대한 링크를 반환하고
초기화된 개체입니다. args 배열의 길이
의 매개변수 개수와 일치해야 합니다.
생성자의 선언 및 배열 요소의 객체 유형은 할당을 허용해야 합니다.
해당 유형의 생성자 매개변수 -
그렇지 않으면 예외가 발생합니다
IllegalArgumentException.

17.

예를 살펴보겠습니다:
클래스 마이클래스(
비공개 int a;
공개 Myclass(int k)(a=k;)
공개 int func(int a,int b)(return a+b;)
}
공개 클래스 메인(
공개 정적 무효 메인(문자열 인수)(
노력하다(
문자열 이름="Myclass";
클래스 mycl=Class.forName(이름);
클래스 d=(int.class);
생성자 c=mycl.getConstructor(d);
Myclass ob=(Myclass)c.newInstance(새 객체(
새로운 정수(10)));
System.out.println(ob.func(3,5)); )
catch(Exception e)();
}}

18.

AccessibleObject 클래스
Field, Constructor 및 Method 클래스는 다음과 같습니다.
AccessibleObject 클래스에서 파생됩니다.
이를 해결하거나
검사 수준 액세스 속성을 비활성화합니다.
공개 및 비공개와 같은 언어.
AccessibleObject 클래스에는 메서드가 있습니다.
1. 공개 무효 setAccessible(부울 플래그)
객체 액세스 플래그를 다음으로 설정합니다.
인수 값에 따라: true
물체가 더 이상 영향을 받지 않는다는 것을 의미합니다.
수준에서 설정된 액세스 규칙
언어(항상 사용 가능), false
객체가 주어진 상태를 유지하도록 강제
액세스 수준.
접근 플래그를 변경할 수 있는 권한인 경우
충분하지 않으면 유형의 예외가 발생합니다.
보안예외

19.

2. 공개 정적
void setAccessible(AccessibleObject 배열,
부울 플래그)
액세스 플래그를 설정할 수 있습니다.
배열로 전달된 객체.
다음 처리가 진행 중인 경우
객체가 유형의 예외를 발생시킵니다.
SecurityException, 객체 위치
이전에 배열에 새로 지정된 것을 저장하십시오.
액세스 수준 값 및 기타 모든 값
객체는 동일한 상태로 유지됩니다.
3. 공개 부울 isAccessible()
액세스 플래그의 현재 값을 반환합니다.
물체에

20.

배열 클래스
Array 클래스는 배열을 생성하는 데 사용됩니다.
반성의 수단.
배열을 생성하는 데 두 가지 형태의 메서드가 사용됩니다.
newInstance.
공용 객체 newInstance(클래스 compType, int 길이)
링크를 반환합니다. 새로운 어레이유형 compType
주어진 길이 길이.
공용 객체 newInstance(클래스 compType, int 희미한)
새로운 다차원 배열 유형에 대한 참조를 반환합니다.
값으로 차원이 지정되는 compType
매개변수 배열의 요소가 희미합니다.
배열의 희미한 값이 비어 있거나 길이가 다음보다 큰 경우
허용되는 차원 수(일반적으로 255)

legalArgumentException.

21.

예를 살펴 보겠습니다.
예시 1. 바이트 유형의 배열을 만들어 보겠습니다.
바이트 ba = (바이트)
Array.newInstance(byte.class,13);
이것은 동등하다
바이트 ba = 새 바이트;
예시 2.
int 희미함 = (4, 4);
이중 행렬 =(이중)
Array.newlnstance(double.class, 희미함);
이것은 동등하다
이중 행렬 = 새로운 이중;

22.

Array 클래스에는 get 및 set 메소드가 있습니다.
int 유형 값의 배열 x가 주어지도록 합니다. 그 다음에
xa[i] 표현식은 다음에 해당합니다.
정수 n=Array.get(xa, i)
다음과 같이 배열 요소에 값을 할당할 수 있습니다.
xa[i] = 23; -이것도 마찬가지야
Array.set(xa, i, new Integer(23));
패키지 클래스
Class 클래스의 getPackage 메소드를 호출하면
다음을 포함하는 Package 클래스 객체를 얻습니다.
포함된 패키지에 대한 설명
클래스(패키지 클래스 자체는 패키지에 있습니다.
java.lang).
Package 개체의 getName() 메서드는 다음을 반환합니다.
현재 패키지의 전체 이름입니다.

23.

프록시 클래스
Proxy 클래스를 사용하면 동적으로 생성할 수 있습니다.
하나 이상을 구현하는 클래스
인터페이스.
A클래스가 있다고 가정해보자.
일부 인터페이스를 구현합니다.
런타임 시 Java 시스템은 다음을 수행할 수 있습니다.
주어진 프록시 클래스를 생성합니다.
클래스 A, 즉 그런 수업
모든 클래스 A 인터페이스를 구현하지만
이들 메소드를 모두 호출하는 것을 대체합니다.
호출 메소드를 호출하는 인터페이스,
InvocationHandler 인터페이스
당신이 결정할 수 있는 것은
구현.

24.

메소드 호출을 사용하여 프록시 클래스가 생성됩니다.
ClassLoader를 사용하는 Proxy.getProxyClass
인터페이스 배열, 객체 반환
클래스 java.lang.Class가 로드됩니다.
ClassLoader를 전달하고 전달된 배열을 구현합니다.
인터페이스.
전달된 매개변수에는 여러 가지 제한사항이 있습니다.
1. 인터페이스 배열의 모든 객체는 다음과 같아야 합니다.
인터페이스. 수업이 될 수 없습니다.
기초 요소.
2. 어레이에는 두 개의 동일한 인터페이스가 있을 수 없습니다.
사물.
3. 인터페이스 배열의 모든 인터페이스는 다음과 같아야 합니다.
메소드에 전달된 ClassLoader에 의해 로드됨
getProxyClass.
4. 모든 비공개 인터페이스를 정의해야 합니다.
동일한 패키지에서 그렇지 않으면 생성된 프록시 클래스
모두 구현할 수는 없습니다.

25.

5. 두 개의 인터페이스를 가질 수 없습니다
이름이 같은 메서드와
매개변수 서명은 다르지만
반환 유형.
6. 인터페이스 배열의 길이는 제한되어 있습니다.
65535 인터페이스. 자바 클래스 없음
65535 이상을 구현할 수 없습니다.
인터페이스.

26.

동적 프록시 클래스 속성
1. 프록시 클래스는 공개입니다.
최종 수정자이며 추상적이지 않습니다.
2. 기본 프록시 클래스 이름은 다음과 같습니다.
정의되었지만 프록시에서 시작됩니다. 모두
Proxy로 시작하는 네임스페이스
프록시 클래스용으로 예약됨
(안에 최신 버전자바는 필수가 아닙니다.)
3. 프록시 클래스는 다음에서 상속됩니다.
java.lang.reflect.Proxy.
4. 프록시 클래스는 모든 인터페이스를 구현합니다.
생성 시 전송 순서대로 전송됩니다.

27.

5. 프록시 클래스가 비공개를 구현하는 경우
인터페이스이면 패키지에 생성됩니다.
이는 가장 비공개적인 것을 정의합니다.
상호 작용. 일반적으로 패키지에는
정의되지 않은 프록시 클래스가 생성됩니다.
6. Proxy.isProxyClass 메서드는 다음에 대해 true를 반환합니다.
다음을 사용하여 생성된 클래스
Proxy.getProxyClass 및 객체 클래스의 경우
Proxy.newProxyInstance를 사용하여 생성되었으며
그렇지 않으면 거짓입니다.
이 방법은 하위 시스템에서 사용됩니다.
Java 보안을 이해해야 합니다.
클래스는 단순히 상속됨
java.lang.reflect.Proxy는 false를 반환합니다.

28.

생성된 프록시 클래스 인스턴스의 속성은 다음과 같습니다.
1. 프록시 클래스 객체를 모든 인터페이스로 가져옵니다.
인터페이스 배열에 전달되었습니다. IDemo가 다음 중 하나인 경우
인터페이스가 전송된 다음 작업의 프록시 인스턴스
IDemo는 항상 true를 반환하고 작업(IDemo) 프록시는
올바르게 종료됩니다.
2. 정적 메소드 Proxy.getInvocationHandler
생성 중에 전달된 호출 핸들러를 반환합니다.
프록시 클래스 인스턴스. 이쪽으로 옮겨지면
메소드 객체가 프록시 클래스의 인스턴스가 아닌 경우
IllegalArgumentException 예외가 발생합니다.
3. 호출 처리기 클래스는 인터페이스를 구현합니다.
호출 메소드를 정의하는 InvocationHandler는,
다음 서명이 있습니다.
공개 객체 호출(객체 프록시, 메소드 메소드,
개체 인수) Throwable을 던졌습니다.

29.

예를 살펴보겠습니다:
패키지 javaapplication3;
인터페이스 계정(
더블 getBalance();
voidchangeBalance(int sum);
무효 퍼센트(더블 퍼);)
MyAccount 클래스는 Account(
개인 이중 잔액;
공개 MyAccount() ( 잔액=0.0; )
public double getBalance() (잔액 반환;)
공개 무효 변경 잔액(int 합계)(
잔액+=합;)
공공 무효율(더블 당)(
잔액+=잔액*100당; ); )

30.

MyAccountProxy 클래스 구현
호출 처리기(
개인 계정 ac;
공개 MyAccountProxy(계정 계정)( ac=acc; )
공용 정적 계정 newInstance(계정 da)(
(계정)Proxy.newProxyInstance(를 반환합니다.
da.getClass().getClassLoader(),
da.getClass().getInterfaces(),
새로운 MyAccountProxy(da));
}

31.

공개 객체 호출(객체 프록시,
메소드 메소드, 객체 인수)
Throwable(
if(method.getName()=="퍼센트")(
double d=((Double)args).doubleValue();
만약(d<0) d=0;
if(d>30) d=30;
args=new Double(d);

또 다른(
return method.invoke(ac, args); )
}
}

32.

공개 클래스 메인(
공개 정적 무효 메인(문자열 인수)(
MyAccount ma=new MyAccount();
계정
a=(계정)MyAccountProxy.newInstance(ma);
a.changeBalance(150);

a.퍼센트(20);
System.out.println(a.getBalance());
a.퍼센트(35);
System.out.println(a.getBalance());) )

33.

클래스 로딩 중
런타임 시스템은 필요에 따라 클래스를 로드합니다.
그들에 대한 필요성이 발생합니다.
로딩 절차의 기능적 특징
수업은 다음에 크게 의존합니다.
구현 가상 머신자바이지만
대부분의 경우 수업을 찾으려면
애플리케이션에서 주소를 지정했지만 로드되지 않았습니다.
실행 시스템, 메커니즘이 사용됩니다
수업 검색 경로를 확인하세요.
할 수 있는 애플리케이션을 만들려면
이외의 방법으로 클래스 로드
기본적으로 제공되므로
ClassLoader 클래스 객체를 사용하고,
원하는 구현의 바이트 코드를 얻을 수 있습니다.
클래스를 만들어 런타임 환경에 로드합니다.
시스템.

34.

ClassLoader 클래스는 추상 클래스입니다.
자신만의 클래스 로더를 생성하려면,
다음의 자손인 클래스를 만들어야 합니다.
ClassLoader 및 재정의 메서드
보호 클래스 findClass(문자열 이름)이 발생합니다.
ClassNotFoundException
주어진 클래스의 바이트 코드를 찾습니다.
name 이름을 지정하고 데이터를 환경에 로드합니다.
클래스 객체를 반환하는 가상 머신,
발견된 클래스를 나타냅니다.
로더 객체는 위임할 수 있습니다.
클래스를 "부모"에 로드하는 권한
클래스 로더(상위 클래스 로더)에.
"상위" 클래스 로더는 다음과 같습니다.
클래스 생성자에 인수로 제공됨
클래스로더.

35.

보호된 클래스로더()
암시적으로 ClassLoader 객체를 생성합니다.
"부모"로 사용
클래스 로더 시스템 로더
(다음을 통해 얻을 수 있습니다.
getSystemClassLoader 메소드를 호출하십시오).
보호된 ClassLoader(ClassLoader 상위)
다음을 사용하여 ClassLoader 객체를 생성합니다.
지정된 "상위" 클래스 로더.
ClassLoader 클래스의 주요 부분
loadClass 메소드입니다

36.

공개 클래스 loadClass(문자열 이름)이 발생합니다.
ClassNotFoundException
주어진 클래스에 대한 Class 객체를 반환합니다.
이름을 지정하고 필요한 경우 이를 로드합니다.
수업. 클래스를 로드할 수 없는 경우
유형의 예외가 발생합니다.
ClassNotFoundException.
방법이 제안하는 클래스 로딩 방식
loadClass는 기본값이며 일반적으로 그렇지 않습니다.
재정의되면 다음과 같습니다.
1. 메소드를 호출하여 확인
ClassLoader의 findLoadedClass, 아님
지정된 클래스가 이전에 로드되었는지 여부; 의 일부로
ClassLoader는 객체 테이블을 제공합니다.
도구에 의해 로드된 모든 클래스에 대한 클래스
현재 클래스 로더; 수업이 있었다면
이전에 로드된 findLoadedClass 메소드
기존 Class 객체에 대한 참조를 반환합니다.

37.

2. 클래스가 로드되지 않은 경우 호출됩니다.
"상위" 로더의 loadClass
클래스; 현재 부트로더가 그렇지 않은 경우
"부모"가 있고 사용됨
시스템 클래스 로더;
3. 클래스가 여전히 로드되지 않은 경우,
findClass 메소드가 호출되어 다음을 수행합니다.
검색하고 수업을 다운로드하세요.
따라서 구현이 필요합니다.
다음 메소드의 사용자 정의 버전
클래스로더:

38.

보호된 동기화 클래스
loadClass(문자열 이름, 부울 해석)

보호 클래스 findClass(문자열 이름)
ClassNotFoundException이 발생합니다.
protected java.net.URL findResource(문자열 이름)
보호된 java.util.Enumeration
findResources(문자열 이름)가 IOException을 발생시킵니다.
(추상 클래스 ClassLoader는
loadClass 메소드 기반의 구현만
보호된 메소드 – findLoadedClass 및 findClass).

39.

예를 살펴보겠습니다.
PlayerLoader 클래스는 ClassLoader를 확장합니다(
공용 클래스 findClass(문자열 이름)이 발생합니다.
ClassNotFoundException(
노력하다 (
byte buf = bytesForClass(이름);
return DefineClass(name, buf, 0, buf.length);
}
잡기 (IOException e) (
throw new ClassNotFoundException(e.toString());
}
}
// ...byteForClass 메소드 및 기타 선언
행동 양식
}

40.

findClass 메소드는 일반적으로 두 가지 작업을 수행합니다.
기능.
먼저 바이트코드를 감지해야 합니다.
주어진 클래스를 배열에 저장
바이트 유형 - 예에서는 이 의무입니다.
bytesForСlass 메소드에 할당됩니다.
둘째, 적용방식을 사용한다.
실제 작업을 수행하기 위한 정의
바이트코드로 정의된 클래스를 로드합니다.
DefineClass 메소드는 다음과 같습니다.

41.

보호된 최종 클래스 정의 클래스(문자열 이름,
바이트 데이터, int 오프셋, int 길이)이 발생합니다.
클래스형식오류
주어진 이름을 가진 클래스에 대한 Class 객체를 반환합니다.
이름; 클래스의 이진 표현이 전달됩니다.
배열 데이터 형태로.
클래스를 로드하는 데 바이트만 사용됩니다.
인덱스가 있는 데이터 배열의 요소에 포함됨
오프셋에서 오프셋+길이로. 지정된 바이트의 경우
간격이 필수 형식을 충족하지 않습니다.
클래스 설명, 예외 객체가 발생합니다.
ClassFormatError를 입력하세요.
메소드는 객체에 대한 참조를 저장하는 역할을 담당합니다.
로드된 테이블에 로드된 클래스에 대한 클래스
findLoadedClass 메소드로 조회된 클래스입니다.

42.

bytesForClass 메소드를 살펴보겠습니다.
보호된 바이트 bytesForClass(문자열 이름)이 발생합니다.
lOException, ClassNotFoundException(
FileInputStream in = null;
노력하다 (


if (length == 0) 새로운 ClassNotFoundException(name)을 던집니다;
바이트 buf = 새 바이트;

버퍼를 반환;
}
마지막으로(
if (in!=null) in.close();
}
}

43.

따라서 전체 코드는 다음과 같습니다.
import java.lang.reflect.*;
import java.io.*;
MyClassLoader 클래스는 ClassLoader(
공개 클래스findClass(문자열 이름)이 발생합니다.
ClassNotFoundException(
바이트 buf=ReadFromBuffer(이름);
if(name.equals("MyInterface1"))(

) else if(buf==null) (
return findSystemClass(이름);
) 또 다른 (
return DefineClass(이름,buf,0,buf.length);
}
}

44.

보호된 바이트 ReadFromBuffer(문자열 이름)이 발생합니다.
ClassNotFoundException(
FileInputStream in = null;
노력하다 (
in = new FileInputStream(이름 + ".class");
int 길이 = in.available(); // 사용 가능한 바이트 수
if (길이 == 0) 던지기
새로운 ClassNotFoundException(이름);
바이트 buf = 새 바이트;
in.read(buf); // 바이트 읽기
버퍼를 반환;
}
catch(FileNotFoundException e)( null을 반환합니다.)
catch(IOException e)( null을 반환함;)
마지막으로(
try( if (in!=null) in.close(); )
catch(IOException e)( )
}
}

45.

보호된 동기화 클래스
loadClass(문자열 이름, 부울 해결)이 발생합니다.
ClassNotFoundException(
클래스 결과= findClass(이름);
if (해결) resolveClass(result);
결과 반환;
}
}

46.

공개 클래스 Main1(
공개 정적 무효 메인(문자열 인수) (
노력하다(
문자열 이름="Myclass";
ClassLoader ld=new MyClassLoader();
클래스 cl=Class.forName(name, true, ld);
생성자 s=cl.getConstructor(int.class);
마이인터페이스1
ob=(MyInterface1)s.newInstance(
새로운 정수(8));
System.out.println(ob.func(3,5));
)catch(예외 e)( );
}
}

47.

공용 인터페이스 MyInterface1(
공개 int func(int a,int b);
}
공개 클래스 Myclass는 MyInterface1을 구현합니다(
비공개 int a;
공개 Myclass(int k) ( a=k; )
공개 int func(int a,int b)( return a+b; )

수정자란 무엇인지, 범위, 클래스 수정자, 필드, 메소드 등 수정자에 대해 이야기하겠습니다. 지루하지 않을 것 같아요.

Java의 수정자- 이것 키워드, 클래스, 클래스 필드 또는 메서드에 특정 속성을 제공합니다.

해당 클래스의 메서드 및 필드 가시성을 나타내기 위해 4개의 액세스 한정자가 있습니다.

  • 사적인클래스 멤버는 클래스 내에서만 액세스할 수 있습니다.
  • package-private 또는 default (기본값)클래스 멤버는 패키지 내부에 표시됩니다.
  • 보호됨클래스 멤버는 패키지 내부와 하위 클래스에서 사용할 수 있습니다.
  • 공공의클래스 멤버는 누구나 사용할 수 있습니다.

마지막에 Cat 클래스를 이미 임포트했을 때에도 여전히 컴파일 오류가 발생했다는 사실을 기억하시나요?

문제는 필드와 메소드에 대한 액세스 한정자를 지정하지 않았으며 기본 속성이 있다는 것입니다(클래스 멤버는 패키지 내부에서 볼 수 있음). 코드의 컴파일 오류를 수정하고 최종적으로 실행하려면 생성자와 메서드를 공개해야 합니다. 그런 다음 다른 패키지에서 호출할 수 있습니다.

당신은 궁금해지기 시작할 수도 있습니다: 이 모든 것이 무엇을 위한 것인가? 모든 패키지나 클래스에서 코드를 볼 수 있도록 하면 안 되지만 액세스를 제한해야 하는 이유는 무엇입니까? 복잡하고 번거로운 프로젝트를 작성해야 할 때가 되면 이러한 질문은 저절로 사라질 것입니다. 이제 기능이 하나 또는 두 개의 클래스로 제한되는 애플리케이션을 작성할 때 아무것도 제한할 필요가 없는 것 같습니다.

특정 제품의 객체를 표시하는 클래스가 있다고 상상해 보세요. 예를 들어 자동차. 자동차에는 가격이 있을 수 있습니다. 가격 필드와 기타 여러 필드, 즉 기능을 담당하는 여러 메서드를 만들었습니다. 모든 것이 괜찮은 것 같습니다. 귀하의 수업용 차량은 거대한 프로젝트의 일부이며 모두가 행복합니다. 그러나 누군가 실수로 또는 의도적으로 자동차 클래스의 인스턴스를 생성하고 음수 가격을 설정했다고 가정해 보겠습니다. 제품 가격이 마이너스일 수 있나요? 이것은 매우 원시적인 예이고 현실에서 이런 일이 일어날 가능성은 거의 없지만 아이디어는 분명하다고 생각합니다. 때로는 직접적으로 액세스 권한을 부여하지 않고 특정 방법을 통해 액세스 권한을 부여해야 하는 경우도 있습니다. 코드가 다른 코드의 기능을 담당할 수 있으며 다른 사람이 자신의 코드 일부를 변경하거나 편집하는 것을 원하지 않을 수 있습니다. 이를 위해 접근 제한이 있습니다.

생성자, 메소드 및 필드에 대한 액세스 한정자는 무엇이든 될 수 있습니다. 클래스는 공개 또는 기본 클래스일 수 있으며, 하나의 파일에는 공개 클래스가 하나만 있을 수 있습니다.

지금은 액세스 수정자에 대해 충분합니다. "객체 지향 프로그래밍" 기사에서 이에 대해 더 자세히 설명할 예정이지만 이제 많은 수정자에 대해 이야기하겠습니다.

이제 수정자가 온다 공전. 중첩 클래스를 선언하려는 경우 메서드, 필드 및 클래스 앞에 사용할 수 있습니다. Java에서는 다른 클래스 내에 클래스를 작성할 수 있으며, 클래스 내부 클래스 앞의 수정자가 정적이면 해당 클래스를 중첩이라고 하고, 다른 수정자가 또는 기본값이면 해당 클래스를 내부라고 합니다. 모든 것이 그렇게 간단하지 않기 때문에 중첩 클래스와 내부 클래스에 대한 별도의 기사가 있을 것입니다.

메서드나 필드 앞에 있는 static 한정자는 해당 클래스의 인스턴스에 속하지 않음을 나타냅니다. 이것이 우리에게 무엇을 의미합니까? 클래스 필드나 메소드를 정적으로 선언하면 클래스 인스턴스를 사용하지 않고도 호출할 수 있습니다. 즉, 다음 구성 대신 Cat cat = new Cat(); cat.method(), 간단히 Cat.method()를 작성할 수 있습니다. 메서드가 정적으로 선언된 경우에 한합니다. 정적 변수는 모든 클래스 객체에 대해 동일합니다. 링크가 하나 있습니다.

    공용 클래스 수정자(

    정적 int anotherStaticField = 5 ;

    공개 정적 무효 myStaticMethod()(

    someField = "내 필드" ;

    //nonStaticField = ""; 컴파일 오류

    //비정적 필드는 사용할 수 없습니다.

    //정적 메소드에서

    공공 무효 myNonStaticMethod() (

    anotherStaticField = 4 ; //정적 필드를 사용할 수 있습니다.

    //비정적 메소드

    //main 메소드에도 정적 수정자가 있습니다.

    새로운 수정자() .myNonStaticMethod() ;

    Modificators.myStaticMethod(); //정적 메소드 및 필드 호출

    //Classname.method를 통해

static 수정자에 대해 알아야 할 또 다른 중요한 점은 클래스가 로드될 때 정적 필드가 초기화된다는 것입니다. 다양한 유형의 Java 테스트에서 다음 코드를 찾을 수 있는 경우가 많습니다.

질문: 콘솔에는 무엇이 출력되나요? 어떤 경우에도 정적 블록이 먼저 출력된다는 점을 기억해야 합니다. 다음은 기본 블록입니다. 다음으로 콘솔 화면을 살펴보세요.

우리가 살펴볼 다음 수정자는 결정적인.

나는 최종이라는 단어가 그 자체로 말해준다고 생각합니다. final 수정자를 사용하면 필드를 변경할 수 없고, 메서드를 재정의할 수 없으며, 클래스를 상속할 수 없다고 말합니다(상속에 대한 별도의 기사가 있을 예정입니다). 이 수정자는 클래스, 메서드 및 변수(지역 변수도 포함)에만 적용됩니다.

OOP 기사에서 메서드와 클래스에 대한 최종 수정자에 대해 이야기하겠습니다.

다음은 초보자나 이 기사 시리즈를 처음부터 읽는 사람들에게는 명확하지 않은 수식어입니다. 그리고 아직 모든 것을 설명할 수는 없지만(부속 자료를 모르기 때문에) 그냥 익숙해지시길 권합니다. 이러한 수식어를 사용할 때가 되면 아래에 사용된 대부분의 용어를 이미 이해하게 될 것입니다.

수정자 동기화됨- 한 번에 하나의 스레드에서만 메서드를 사용할 수 있음을 나타냅니다. 이것이 아무 것도 알려주지 않을 수도 있지만 이 수정자의 유용성은 멀티스레딩을 연구할 때 알게 될 것입니다.

수정자 과도 현상— 객체 직렬화 중에 특정 필드를 무시해야 함을 나타냅니다. 일반적으로 이러한 필드는 중간 값을 저장합니다.

수정자 휘발성 물질- 멀티스레딩에 사용됩니다. 휘발성 수정자가 있는 필드가 여러 스레드에 의해 사용되고 변경될 때 이 수정자는 필드가 차례로 변경되고 혼동되지 않도록 보장합니다.

수정자 토종의메소드를 선언하기 전에 메소드가 다른 프로그래밍 언어로 작성되었음을 나타냅니다. 보통 C언어로 되어있습니다.

수정자 엄격한— 부동 소수점 및 이중 숫자(부동 소수점)에 대한 연산이 IEEE 754 표준에 따라 수행되도록 보장합니다. 또는 더 간단히 말하면 메서드 내에서 계산 결과가 모든 플랫폼에서 동일함을 보장합니다.

아직 수식어에 대해 이야기하지 않았습니다. 추상적인. 객체 지향 프로그래밍의 기본 지식이 없으면 이에 대해 이야기할 필요가 없기 때문에 간략하게 이야기하겠습니다.

abstract 한정자가 있는 클래스는 인스턴스를 만들 수 없습니다. 그것의 유일한 목적은 확장하는 것입니다. 추상 클래스에는 추상 메서드와 일반 메서드가 모두 포함될 수 있습니다.

OOP 기사에서 추상 수정자에 대해 더 자세히 설명하겠습니다.

여기서 수정자에 대한 기사를 마무리할 수 있습니다. 그들에 대해 많이 언급되지 않았습니다. 그러나 이는 아직 OOP 개념이 없기 때문입니다. 여러 기사를 통해 수정자에 대한 지식을 확장하고 공백을 메울 것입니다.

마지막 업데이트: 2019년 10월 3일

클래스의 모든 멤버(필드, 메소드, 속성)는 모두 액세스 수정자. 액세스 한정자를 사용하면 클래스 멤버에 대해 허용되는 범위를 지정할 수 있습니다. 즉, 액세스 한정자는 주어진 변수나 메서드가 사용될 수 있는 컨텍스트를 결정합니다. 이전 주제에서 우리는 클래스의 필드를 public으로 선언할 때(즉, public 한정자를 사용하여) 이미 이를 접했습니다.

C#에서는 다음 액세스 한정자가 사용됩니다.

    public : 공개, 공개 클래스 또는 클래스 멤버입니다. 이러한 클래스 멤버는 코드의 어느 곳에서나 다른 프로그램 및 어셈블리에서 액세스할 수 있습니다.

    private : 비공개 클래스 또는 클래스 멤버입니다. public 한정자의 정반대를 나타냅니다. 이러한 전용 클래스 또는 클래스 멤버는 동일한 클래스 또는 컨텍스트의 코드에서만 액세스할 수 있습니다.

    protected : 이 클래스 멤버는 현재 클래스나 파생 클래스의 어디에서나 액세스할 수 있습니다. 이 경우 파생 클래스는 다른 어셈블리에 있을 수 있습니다.

    내부: 유사한 한정자를 가진 클래스 및 클래스 멤버는 동일한 어셈블리의 코드 어디에서나 액세스할 수 있지만 다른 프로그램이나 어셈블리에서는 액세스할 수 없습니다(public 한정자의 경우와 마찬가지로).

    protected 내부: 두 수정자의 기능을 결합합니다. 이 수정자를 사용하는 클래스 및 클래스 멤버는 현재 어셈블리 및 파생 클래스에서 액세스할 수 있습니다.

    private protected: 이 클래스 멤버는 현재 클래스나 동일한 어셈블리에 정의된 파생 클래스의 어느 곳에서나 액세스할 수 있습니다.

다음과 같이 액세스 한정자를 명시적으로 설정할 수 있습니다.

개인 보호 클래스 상태 ( 내부 int a; protected void Print() ( Console.WriteLine($"a = (a)"); ) )

또는 다음 사항을 표시하지 않을 수도 있습니다.

클래스 상태 ( int a; void Print() ( Console.WriteLine($"a = (a)"); ) )

필드와 메소드에 액세스 한정자가 정의되어 있지 않으면 기본 한정자는 private 입니다.

수정자 없이 선언된 클래스 및 구조체에는 기본적으로 내부 액세스 권한이 있습니다.

네임스페이스에 직접 정의되고 다른 클래스 내에 중첩되지 않은 모든 클래스 및 구조는 public 또는 Internal 한정자만 가질 수 있습니다.

예제를 살펴보고 다음 State 클래스를 만들어 보겠습니다.

Public class State ( // private int defaultVar; int defaultVar; // 필드는 현재 클래스에서만 접근 가능합니다. private int privateVar; // 현재 클래스와 같은 프로젝트에 정의된 파생 클래스에서만 접근 가능합니다. protected private int protectedPrivateVar; // 현재 클래스 및 파생 클래스에서 사용 가능 protected int protectedVar; // 현재 프로젝트의 어느 곳에서나 사용 가능 Internal int InternalVar; // 현재 프로젝트의 어느 곳에서나 사용 가능하며 다른 프로젝트의 하위 클래스에서도 사용 가능 protected Internal int protectedInternalVar; / / 다른 프로그램 및 어셈블리뿐만 아니라 프로그램의 어느 곳에서나 사용 가능 public int publicVar; // 기본적으로 수정자가 있습니다. private void defaultMethod() => Console.WriteLine($"defaultVar = (defaultVar)"); // 이 메소드는 현재 클래스에서만 접근 가능합니다. private void privateMethod() => Console.WriteLine($"privateVar = (privateVar)"); // 현재 클래스와 동일한 프로젝트에 정의된 파생 클래스에서만 접근 가능 protected private void protectedPrivateMethod() => Console.WriteLine($ "protectedPrivateVar = (protectedPrivateVar)"); // 현재 클래스 및 파생 클래스에서 액세스 가능 protected void protectedMethod()=> Console.WriteLine($"protectedVar = (protectedVar)"); // 현재 프로젝트의 어느 곳에서나 사용 가능 Internal void InternalMethod() => Console.WriteLine($"internalVar = (internalVar)"); // 현재 프로젝트의 어디에서나 다른 프로젝트의 하위 클래스에서 액세스 가능 protected inner void protectedInternalMethod() => Console.WriteLine($"protectedInternalVar = (protectedInternalVar)"); // 다른 프로그램 및 어셈블리뿐만 아니라 프로그램의 어느 곳에서나 사용 가능 public void publicMethod() => Console.WriteLine($"publicVar = (publicVar)"); )

State 클래스는 public 한정자를 사용하여 선언되므로 프로그램의 어느 곳에서나 다른 프로그램 및 어셈블리에서 액세스할 수 있습니다. State 클래스에는 각 액세스 수준에 대한 5개의 필드가 있습니다. 게다가 기본적으로 비공개인 수정자가 없는 변수 1개.

클래스 필드 값을 화면에 표시하는 방법도 6가지가 있습니다. 모든 수정자는 지정된 클래스 내에서 클래스 멤버의 사용을 허용하므로 모든 클래스 변수는 State 클래스의 컨텍스트에 있으므로 개인 변수를 포함한 모든 클래스 변수를 모든 메서드에서 사용할 수 있습니다.

이제 State 및 Program 클래스가 동일한 프로젝트에 있는 경우 프로그램(즉, Program 클래스의 Main 메서드)에서 클래스 변수를 사용할 수 있는 방법을 살펴보겠습니다.

Class Program ( static void Main(string args) ( State state1 = new State(); // defaultVar 변수에 값을 할당할 수 없습니다. // 변수에는 private 수정자가 있고 Program 클래스는 이를 볼 수 없기 때문입니다. 그것 // 그리고 이 줄환경은 잘못된 state1.defaultVar = 5로 강조 표시됩니다. //오류, 접근을 얻을 수 없습니다. // 변수 privateVar에도 동일하게 적용됩니다. state1.privateVar = 5; // 오류, 액세스를 얻을 수 없습니다. // protectedPrivateVar 변수에 값을 할당하면 작동하지 않습니다. // Program 클래스는 State 클래스의 하위 클래스가 아니기 때문입니다. state1.protectedPrivateVar =5; // 오류, 액세스를 얻을 수 없습니다. // protectedVar 변수에 값을 할당하는 것도 작동하지 않습니다. // Program 클래스가 State 클래스의 하위 클래스가 아니기 때문입니다. state1.protectedVar = 5; // 오류, 액세스할 수 없습니다. // 내부 수정자가 있는 InternalVar 변수는 현재 프로젝트의 어느 곳에서나 액세스할 수 있으므로 // 값을 침착하게 state1.internalVar = 5; // protectedInternalVar 변수는 현재 프로젝트의 어느 곳에서나 액세스할 수 있습니다. state1.protectedInternalVar = 5; // publicVar 변수는 public입니다. state1.publicVar = 5; ) )

따라서 우리는 변수 innerVar, protectedInternalVar 및 publicVar만 설정할 수 있었습니다. 해당 수정자는 이 컨텍스트에서 사용을 허용하기 때문입니다.

상황은 메소드와 유사합니다.

클래스 프로그램 ( static void Main(string args) ( State state1 = new State(); state1.defaultMethod(); // 오류, 액세스에 액세스할 수 없습니다. state1.privateMethod(); // 오류, 액세스에 액세스할 수 없습니다. state1.protectedPrivateMethod () ; // 오류, 액세스 권한을 얻을 수 없습니다. state1.protectedMethod(); // 오류, 액세스 권한을 얻을 수 없습니다. state1.internalMethod(); // 괜찮습니다. state1.protectedInternalMethod(); // 괜찮습니다. state1.publicMethod(); / / 좋아요 ) )

여기서는 innerMethod, protectedInternalMethod, publicMethod의 세 가지 메소드만 사용할 수 있었으며 각각 내부, 보호된 내부, 공개 수정자가 있습니다.

이 접근 한정자 시스템 덕분에 프로그램의 다른 부분에서 클래스 구현의 일부 측면을 숨길 수 있습니다.

공개 수식자와 내부 수식자는 효과가 유사함에도 불구하고 큰 차이가 있습니다. public 한정자가 있는 클래스 및 클래스 멤버는 이 클래스가 동적 라이브러리 dll에 배치된 다음 이러한 프로그램에서 사용되는 경우 다른 프로그램에서도 사용할 수 있습니다.

마지막 업데이트: 2018년 4월 20일

Java의 모든 클래스 멤버(필드 및 메소드)에는 액세스 수정자가 있습니다. 이전 주제에서 우리는 이미 public 수정자를 접했습니다. 액세스 한정자를 사용하면 클래스 멤버에 허용되는 범위, 즉 주어진 변수나 메서드를 사용할 수 있는 컨텍스트를 설정할 수 있습니다.

Java는 다음 액세스 한정자를 사용합니다.

    public : 공개, 공개 클래스 또는 클래스 멤버입니다. public 한정자로 선언된 필드와 메서드는 현재 패키지와 외부 패키지의 다른 클래스에서 볼 수 있습니다.

    private : public 한정자와 반대되는 private 클래스 또는 클래스 멤버입니다. 전용 클래스 또는 클래스 멤버는 동일한 클래스의 코드에서만 액세스할 수 있습니다.

    protected: 해당 클래스나 클래스 멤버는 현재 클래스나 패키지 또는 파생 클래스의 어느 곳에서나 액세스할 수 있습니다. 다른 패키지에 있더라도 마찬가지입니다.

    기본 수정자. 클래스 필드 또는 메서드에 수정자가 없으면 기본 수정자가 적용된다는 의미입니다. 이러한 필드나 메서드는 현재 패키지의 모든 클래스에 표시됩니다.

다음 프로그램을 예로 사용하여 액세스 수정자를 살펴보겠습니다.

Public class Program( public static void main(String args) ( Person kate = new Person("Kate", 32, "Baker Street", "+12334567"); kate.displayName(); // 일반, 메소드 public kate. displayAge(); // 좋아요, 메소드에는 기본 수정자가 있습니다 kate.displayPhone(); // 좋아요, 메소드 보호 //kate.displayAddress(); // ! 오류, 메소드 private System.out.println(kate.name ) ; // 좋습니다, 기본 수정자 System.out.println(kate.address); // 좋습니다, 수정자 public System.out.println(kate.age); // 좋습니다, 수정자 protected //System.out.println( kate.phone); // !오류, 수정자 private ) ) class Person( 문자열 이름; 보호된 정수 나이; 공개 문자열 주소; 개인 문자열 전화; 공개 사람(문자열 이름, 정수 나이, 문자열 주소, 문자열 전화)( this. name = 이름; this.age = 나이; this.address = 주소; this.phone = 전화; ) public void displayName())( System.out.printf("이름: %s \n", name); ) void displayAge ()( System.out.printf("연령: %d \n", age); ) private void displayAddress())( System.out.printf("주소: %s \n", address); ) protected void displayPhone())( System.out.printf("전화: %s \n", 전화); ))

이 경우 두 클래스는 모두 기본 패키지인 하나의 패키지에 있으므로 Program 클래스에서는 기본 수정자 public 및 protected를 갖는 Person 클래스의 모든 메서드와 변수를 사용할 수 있습니다. 그리고 Program 클래스의 private 한정자가 있는 필드와 메서드는 사용할 수 없습니다.

Program 클래스가 다른 패키지에 있는 경우 public 한정자가 있는 필드와 메서드만 사용할 수 있습니다.

액세스 한정자는 나머지 변수 또는 메서드 정의보다 앞에 와야 합니다.

캡슐화

패키지나 클래스에 관계없이 프로그램의 어느 곳에서나 사용할 수 있도록 public 수정자를 사용하여 모든 변수와 메서드를 선언하면 어떨까요? 나이를 나타내는 age 필드를 예로 들어보겠습니다. 다른 클래스가 이 필드에 직접 액세스할 수 있는 경우 프로그램 작동 중에 잘못된 값(예: 음수)이 전달될 가능성이 있습니다. 이러한 데이터 수정은 바람직하지 않습니다. 또는 일부 데이터에 직접 액세스하여 콘솔에 표시하거나 해당 값을 알아낼 수 있기를 원합니다. 이러한 점에서 데이터에 대한 접근을 최대한 제한하여 외부로부터의 원치 않는 접근(가치 획득 및 변경 모두)으로부터 데이터를 보호하는 것이 좋습니다. 다양한 수정자를 사용하면 데이터가 부적절하게 왜곡되거나 변경되지 않습니다. 범위 내에서 이러한 방식으로 데이터를 숨기는 것을 캡슐화라고 합니다.

따라서 원칙적으로 필드를 직접 사용하는 대신 액세스 방법을 사용하는 것이 일반적입니다. 예를 들어:

공용 클래스 Program( public static void main(String args) ( Person kate = new Person("Kate", 30); System.out.println(kate.getAge()); // 30 kate.setAge(33); System .out.println(kate.getAge()); // 33 kate.setAge(123450); System.out.println(kate.getAge()); // 33 ) ) class Person( private String name; private int age ; public Person(문자열 이름, int age)( this.name = 이름; this.age = age; ) public String getName())( return this.name; ) public void setName(문자열 이름)( this.name = 이름 ; ) public int getAge() ( return this.age; ) public void setAge(int age)( if(age > 0 && age< 110) this.age = age; } }

그런 다음 Person 클래스의 이름 및 연령 필드를 직접 사용하는 대신 이러한 필드의 값을 설정하고 반환하는 메서드를 사용하여 작업하겠습니다. setName, setAge 등의 메소드는 필드 값을 변경하므로 mutater라고도 합니다. getName, getAge 등의 메소드를 접근자라고 합니다. 접근자의 도움을 받아 필드 값을 얻을 수 있기 때문입니다.

또한 이러한 메서드에 추가 논리를 넣을 수도 있습니다. 예를 들어, 이 경우 연령이 변경되면 새 값이 허용 범위에 얼마나 잘 맞는지 확인하는 작업이 수행됩니다.

공유하다