복붙노트

[SPRING] 특성의 구체적인 함수 구현이 스칼라 2.9.x에서는 메서드를 연결하도록 컴파일되었지만 2.8.x에서는 그렇지 않은 이유는 무엇입니까?

SPRING

특성의 구체적인 함수 구현이 스칼라 2.9.x에서는 메서드를 연결하도록 컴파일되었지만 2.8.x에서는 그렇지 않은 이유는 무엇입니까?

2.9.0 이전의 스칼라 버전에서는 특성의 구체적인 함수 구현이 일반적인 방법으로 컴파일되었습니다. 2.9.x 이후부터는 브리지 메소드로 컴파일됩니다. Spring과 Jersey 같은 많은 인기있는 Java 프레임 워크의 사용자에게 부정적인 영향을 미치기 때문에이 변경 사항의 추론을 찾으려고합니다.

다음 스칼라 코드를 고려하십시오.

trait Speaks {
  def speak() = {
    println("woof")
  }
}

class Dog extends Speaks {
  def wag() = {
    println("wag wag")
  }
}

Dog 클래스가 scalac 버전 2.8.1로 컴파일되고 javap로 디 컴파일 될 때 "speak"및 "wag"함수의 결과는 다음과 같습니다.

public void speak();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokestatic  #11                 // Method Speaks$class.speak:(LSpeaks;)V
         4: return        
      LineNumberTable:
        line 7: 0

public void wag();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #18                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
         3: ldc           #20                 // String wag wag
         5: invokevirtual #24                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
         8: return        
      LineNumberTable:
        line 9: 0

Dog가 scalac 버전 2.9.1로 컴파일되고 다시 디 컴파일 될 때, 같은 두 함수는 다음과 같습니다 :

public void speak();
  flags: ACC_PUBLIC, ACC_BRIDGE
  Code:
    stack=1, locals=1, args_size=1
       0: aload_0       
       1: invokestatic  #11                 // Method Speaks$class.speak:(LSpeaks;)V
       4: return        
    LineNumberTable:
      line 7: 0

public void wag();
  flags: ACC_PUBLIC
  Code:
    stack=2, locals=1, args_size=1
       0: getstatic     #18                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
       3: ldc           #20                 // String wag wag
       5: invokevirtual #24                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
       8: return        
    LineNumberTable:
      line 9: 0

문제가되는 부분은 speak () 함수에 ACC_BRIDGE 플래그를 추가하는 것입니다. Jersey 및 Spring과 같은 프레임 워크는 의도적으로 다른 문제에 대한 해결 방법으로 브리지 방법을 인식하지 못합니다.

그렇다면 왜 스칼라 2.9.x에서이 변경이 이루어진 이유에 대해 누구나 설명하거나 설명 할 수 있습니까?

추가 답변으로 함수 주석, 컴파일러 플래그 등을 통해이 동작을 비활성화하는 방법이 있습니까?

해결법

  1. ==============================

    1.그것이 의도적 인 변화가 아니었기 때문에 이유에 대한 설명이없는 것처럼 들리네. 이 스레드보기 : http://groups.google.com/group/scala-language/browse_thread/thread/67f8884081d46912

    그것이 의도적 인 변화가 아니었기 때문에 이유에 대한 설명이없는 것처럼 들리네. 이 스레드보기 : http://groups.google.com/group/scala-language/browse_thread/thread/67f8884081d46912

    그리고 해결책은 최신 스냅 샷을 사용하는 것입니다. 읽는 동안 미래가 나타나면 Scala 2.10

  2. from https://stackoverflow.com/questions/8748625/why-are-concrete-function-implementations-in-traits-compiled-to-bridge-methods-i by cc-by-sa and MIT license