Java에서의 합성 클래스
Java에서 합성 클래스가 뭐죠?왜 사용해야 합니까?어떻게 사용할 수 있나요?
Java에는 런타임에 클래스를 만드는 기능이 있습니다.이러한 클래스를 Synthetic Classes 또는 Dynamic Proxy라고 합니다.
상세한 것에 대하여는, http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html 를 참조해 주세요.
CGLIB 및 ASM 등의 기타 오픈소스 라이브러리에서도 모의 클래스를 생성할 수 있으며 JRE에서 제공되는 라이브러리보다 강력합니다.
모의 클래스는 Spring AOP 및 Aspect J와 같은 AOP(Aspect Oriented Programming) 라이브러리와 휴지 상태 등의 ORM 라이브러리에서 사용됩니다.
구글에서 첫 번째 질문에 대한 답을 찾았습니다.
클래스가 컴파일러에 의해 생성된 경우, 즉 소스 코드에 표시되지 않는 경우 클래스가 합성 클래스로 표시될 수 있습니다.
이것은 기본적인 정의일 뿐이지만, 나는 포럼 스레드에서 그것을 발견했고, 설명은 없었다.더 좋은 걸 찾는 중인데...
예를 들어 switch 문이 있는 경우 java는 $로 시작하는 변수를 만듭니다.예를 들어 switch 문이 포함된 클래스의 Java 리플렉션을 확인합니다.클래스 내 임의의 위치에 적어도1개의 스위치문이 있는 경우 이러한 변수가 표시됩니다.
질문에 답하기 위해, 저는 당신이 (반영 이외의) 합성 클래스에 액세스할 수 있다고 생각하지 않습니다.
(반사를 통해) 아무것도 모르는 클래스를 분석하고 해당 클래스에 대해 매우 구체적이고 낮은 수준의 내용을 알아야 하는 경우 합성 클래스와 관련된 Java 반사 메서드를 사용하게 될 수 있습니다.여기서 유일한 "사용"은 코드에서 적절하게 사용하기 위해 클래스에 대한 자세한 정보를 얻는 것입니다.
(이 작업을 하고 있다면 다른 개발자가 사용할 수 있는 프레임워크를 구축하고 있을 것입니다.)
그렇지 않으면 리플리테이션을 사용하지 않으면 합성 클래스가 실제로 사용되지 않는 것으로 알고 있습니다.
합성 클래스/메서드/필드:
이러한 사항은 VM에 중요합니다.다음의 코드 스니펫을 참조해 주세요.
class MyOuter {
private MyInner inner;
void createInner() {
// The Compiler has to create a synthetic method
// to construct a new MyInner because the constructor
// is private.
// --> synthetic "constructor" method
inner = new MyInner();
// The Compiler has to create a synthetic method
// to doSomething on MyInner object because this
// method is private.
// --> synthetic "doSomething" method
inner.doSomething();
}
private class MyInner {
// the inner class holds a syntetic ref_pointer to
// the outer "parent" class
// --> synthetic field
private MyInner() {
}
private void doSomething() {
}
}
}
이 논의에 따르면 언어 사양은 클래스의 "isSynthetic" 프로프리티를 기술하고 있지만 구현에서는 거의 무시되며 동적 프록시 또는 익명 클래스에는 사용되지 않습니다.합성 필드 및 컨스트럭터는 중첩된 클래스를 구현하는 데 사용됩니다(바이트 코드에는 중첩된 클래스 개념이 없고 소스 코드에만 있습니다).
나는 합성 수업의 개념이 유용하지 않다는 것이 증명되었다고 생각한다. 즉, 아무도 수업이 합성인지 아닌지는 신경 쓰지 않는다.필드와 메서드에서는 IDE 클래스 구조 보기에 표시할 내용을 결정하기 위해 일반 메서드와 필드를 표시해야 하지만 중첩된 클래스를 시뮬레이션하는 데 사용되는 합성 메서드와 필드는 표시되지 않아야 합니다.OTOH, 당신은 익명의 수업이 거기에 나타나길 원합니다.
디버깅을 위해 내부 클래스의 개인 멤버를 호출할 때 런타임에 JVM에 의해 생성됩니다.
실행 시 JVM이 작성한 메서드, 필드, 클래스를 Synthetic이라고 합니다.
http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html
http://javapapers.com/core-java/java-synthetic-class-method-field/
다양한 답변이 이미 지적되었듯이 컴파일러는 소스 코드의 무언가에 직접 대응하지 않는 다양한 구성(클래스 포함)을 생성할 수 있습니다.이것들은 합성이라고 마크할 필요가 있습니다.
클래스 또는 인터페이스의 바이너리 표현에는 다음 항목도 모두 포함되어야 합니다.
[...]
(11) Java 컴파일러에 의해 출력된 컨스트럭트는 소스 코드에서 명시적으로 또는 암묵적으로 선언된 컨스트럭트에 대응하지 않는 경우에는 합성이라고 마크해야 한다(JVMS 2 2.9).
[...]
다른 질문에 대한 코멘트에서 @Holger가 지적한 것처럼 메서드 참조와 람다를 나타내는 클래스 오브젝트가 이러한 구성에 관련된 예입니다.
System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());
출력:
true
true
이는 명시적으로 언급되지 않았지만 15.27.4부터 이어집니다. 람다 식의 런타임 평가:
람다 식 값은 다음 속성을 가진 클래스의 인스턴스에 대한 참조입니다. [...]
방법 참조에 대한 거의 동일한 표현(15.13.3. 방법 참조의 런타임 평가).
이 클래스는 소스 코드 어디에도 명시적으로 언급되어 있지 않기 때문에 합성이어야 합니다.
Java에서 합성 클래스가 뭐죠?
A syntheticclass는 a입니다..class파일이 Java 컴파일러에 의해 생성되었지만 소스 코드에 존재하지 않습니다.
사용 예syntheticclass: 익명 내부 클래스
- java.text.DigitList$1은
syntheticjava.text 내의 익명 내부 클래스입니다.디짓 리스트 - 그리고 다음과 같은 이름의 소스 코드 파일은 없습니다.
DigitList$1.java하지만 이것은 내부 파일입니다.DigitList.java
왜 사용해야 합니까?
이것은 Java 컴파일러 로직 내의 메커니즘으로,.class파일
어떻게 사용할 수 있나요?
아니요, 개발자는 직접 사용하지 않습니다.
Java 컴파일러 사용synthetic만들어 내다.classJVM이 파일을 읽습니다..class프로그램 로직을 실행하는 파일입니다.
상세
또한 Synthetic Classes 또는 Dynamic Proxies는 EasyMock에서 실행 시 인터페이스 또는 추상 클래스의 구현을 만들기 위해 사용됩니다.
Java 컴파일러는 내부 클래스와 같은 특정 구성 요소를 컴파일할 때 합성 구성 요소를 만듭니다. 이러한 구성 요소는 클래스, 메서드, 필드 및 소스 코드에 대응하는 구성 요소가 없습니다.
용도: 합성 구조를 사용하면 Java 컴파일러가 JVM을 변경하지 않고 새로운 Java 언어 기능을 구현할 수 있습니다.그러나 합성 구조는 Java 컴파일러 구현마다 다를 수 있습니다.즉, .class 파일은 구현마다 다를 수 있습니다.
레퍼런스 : docs.oracle.com
제가 맞힌다면 합성 클래스는 명시적인 이름을 붙일 필요 없이 즉석에서 생성된 클래스입니다.예를 들어 다음과 같습니다.
//...
Thread myThread = new Thread() {
public void run() {
// do something ...
}
};
myThread.start();
//...
그러면 스레드의 합성 서브클래스가 생성되고 스레드의 run() 메서드가 덮어쓰며 스레드가 인스턴스화되어 시작됩니다.
합성 클래스는 코드에 표시되지 않습니다.컴파일러에 의해 구성됩니다.예: Java의 컴파일러가 구성하는 브리지 방식은 일반적으로 합성 방식입니다.
public class Pair<T> {
private T first;
private T second;
public void setSecond(T newValue) {
second = newValue;
}
}
public class DateInterval extends Pair<String> {
public void setSecond(String second) {
System.out.println("OK sub");
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
DateInterval interval = new DateInterval();
Pair pair = interval;
pair.setSecond("string1");
}
}
명령어 사용javap -verbose DateInterval브릿지 방식은 다음과 같습니다.
public void setSecond(java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
이것은 컴파일러에 의해 작성되었습니다.코드에 표시되지 않습니다.
합성 구조물은 소스 코드에 대응하는 구조가 없는 클래스, 메서드, 필드 등입니다.합성 구조를 사용하면 Java 컴파일러가 JVM을 변경하지 않고 새로운 Java 언어 기능을 구현할 수 있습니다.그러나 합성 구조는 Java 컴파일러 구현마다 다를 수 있습니다.즉, .class 파일은 구현마다 다를 수 있습니다.
언급URL : https://stackoverflow.com/questions/399546/synthetic-class-in-java
'programing' 카테고리의 다른 글
| MySQL의 "IF EXISTES" 사용 방법 (0) | 2022.11.08 |
|---|---|
| mysql의 max(길이(필드)) (0) | 2022.11.08 |
| x**.5와 math.sqrt(x) 중 어느 쪽이 Python에서 더 빠릅니까? (0) | 2022.11.07 |
| 리액트 후크 useState()와 오브젝트 (0) | 2022.11.07 |
| mariadb 이미지에 대해 루트 사용자가 아닌 도커 컨테이너를 실행할 수 없습니다. (0) | 2022.11.07 |