Java의 합성 클래스는 무엇입니까? 왜 사용해야합니까? 어떻게 사용하나요?
Java의 합성 클래스는 무엇입니까? 왜 사용해야합니까? 어떻게 사용하나요?
답변:
예를 들어, switch 문이 있으면 java는 $로 시작하는 변수를 만듭니다. 이에 대한 예제를 보려면 switch 문이 포함 된 클래스의 Java 리플렉션을 살펴보십시오. 클래스 어딘가에 적어도 하나의 switch 문이있을 때 이러한 변수가 표시됩니다.
귀하의 질문에 대답하기 위해 합성 클래스에 액세스 할 수 있다고 생각하지 않습니다.
리플렉션을 통해 알지 못하는 클래스를 분석하고 해당 클래스에 대해 매우 구체적이고 저수준 인 것을 알아야하는 경우 합성 클래스와 관련된 Java 리플렉션 방법을 사용할 수 있습니다. 여기서 유일한 "사용"은 코드에서 클래스를 적절하게 사용하기 위해 클래스에 대한 자세한 정보를 얻는 것입니다.
(이 작업을 수행하는 경우 다른 개발자가 사용할 수있는 일종의 프레임 워크를 구축하고있을 것입니다.)
그렇지 않으면 리플렉션을 사용하지 않는 경우 내가 아는 합성 클래스를 실제로 사용하지 않습니다.
Java는 런타임에 클래스를 작성할 수 있습니다. 이러한 클래스를 합성 클래스 또는 동적 프록시라고합니다.
자세한 내용은 http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html 을 참조하십시오.
CGLIB 및 ASM 과 같은 다른 오픈 소스 라이브러리 도 합성 클래스를 생성 할 수 있으며 JRE와 함께 제공된 라이브러리보다 강력합니다.
합성 클래스는 Spring AOP 및 AspectJ와 같은 AOP (Aspect Oriented Programming) 라이브러리와 Hibernate와 같은 ORM 라이브러리에서 사용됩니다.
Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
java.lang.reflect.Member#isSynthetic
says : 이 멤버가 컴파일러에 의해 도입 된 경우 true를 리턴합니다. 그렇지 않으면 false를 반환합니다.
java.lang.reflect.Member#isSynthetic
이 원래의 질문과 관련이 없다고 생각합니다 . 멤버는 필드, 생성자 및 메서드입니다. 원래 질문은 합성 멤버가 아니라 합성 클래스 에 관한 것이 었습니다 . Java 8에서 람다 식은 합성 클래스를 생성합니다. 다른 상황이 발생할 수 있는지 잘 모르겠습니다.
합성 수업 / 방법 / 분야 :
이러한 것들이 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/
또한 EasyMock은 런타임에 인터페이스 또는 추상 클래스의 구현을 작성하기 위해 합성 클래스 또는 동적 프록시를 사용합니다.
Java 컴파일러는 내부 클래스와 같은 특정 구문을 컴파일 할 때 합성 구문을 만듭니다 . 이들은 클래스, 메소드, 필드 및 소스 코드에 해당 구문이없는 기타 구문입니다.
용도 :
합성 구조를 통해 Java 컴파일러는 JVM을 변경하지 않고도 새로운 Java 언어 기능을 구현할 수 있습니다. 그러나 합성 구문은 Java 컴파일러 구현마다 다를 수 있습니다. 즉, .class 파일도 구현마다 다를 수 있습니다.
참조 : docs.oracle.com
다양한 답변이 이미 지적했듯이 컴파일러는 소스 코드의 내용과 직접적으로 일치하지 않는 다양한 구문 (클래스 포함)을 생성 할 수 있습니다. 이들은 합성으로 표시되어야합니다.
클래스 또는 인터페이스에 대한 이진 표현은 다음을 모두 포함해야합니다.
[...]
11. Java 컴파일러가 생성 한 구성이 소스 코드에서 명시 적 또는 암시 적으로 선언 된 구성과 일치하지 않으면 합성으로 표시되어야합니다. 생성 된 구문이 클래스 초기화 방법이 아닌 경우 (JVMS §2.9)
[...]
다른 질문에 대한 주석에서 @Holger 가 지적한 것처럼 이러한 구문의 관련 예제는 메소드 참조 및 람다를 나타내는 Class 객체입니다.
System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());
산출:
true
true
이것은 명시 적으로 언급되어 있지 않지만 15.27.4 부터 따릅니다. Lambda 식의 런타임 평가 :
람다 식의 값은 다음 속성을 가진 클래스의 인스턴스에 대한 참조입니다. [...]
그리고 메소드 참조에 대한 거의 동일한 표현 ( 15.13.3. 메소드 참조의 런타임 평가 ).
이 클래스는 소스 코드의 어느 곳에서도 명시 적으로 언급되지 않았으므로 합성되어야합니다.
내가 올바르게 이해하면 합성 클래스는 명시적인 이름을주지 않고 즉시 생성됩니다. 예를 들면 다음과 같습니다.
//...
Thread myThread = new Thread() {
public void run() {
// do something ...
}
};
myThread.start();
//...
그러면 Thread의 합성 서브 클래스가 생성되고 run () 메서드가 재정의 된 다음 인스턴스화되어 시작됩니다.
Outer$1.class
.
Java의 합성 클래스는 무엇입니까?
synthetic
클래스는 인 .class
에 의해 생성 된 파일 자바 컴파일러 과 소스 코드에 존재하지 않습니다.
synthetic
클래스 사용 예 : 익명 내부 클래스
synthetic
클래스이며 java.text.DigitList 내부의 익명 내부 클래스입니다.DigitList$1.java
없지만 내부 파일입니다.DigitList.java
왜 사용해야합니까?
.class
파일 을 생성하는 것은 Java 컴파일러 논리 내부의 메커니즘입니다.
어떻게 사용하나요?
아니요, 개발자는 직접 사용 하지 않습니다 .
Java 컴파일러 synthetic
는 .class
파일 을 생성 하는 데 사용 하고 JVM은 .class
파일을 읽어 프로그램 논리를 실행합니다.
합성 구문은 소스 코드에 해당 구문이없는 클래스, 메서드, 필드 등입니다. 합성 구조를 통해 Java 컴파일러는 JVM을 변경하지 않고도 새로운 Java 언어 기능을 구현할 수 있습니다. 그러나 합성 구문은 Java 컴파일러 구현마다 다를 수 있습니다. 즉, .class 파일도 구현마다 다를 수 있습니다.
합성 클래스는 코드에 나타나지 않습니다. 컴파일러로 구성됩니다. 예를 들어, 자바에서 컴파일러가 구성하는 브리지 방법은 일반적으로 합성입니다.
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
이것은 컴파일러에 의해 구성되었습니다. 코드에 나타나지 않습니다.