2012-04-29 38 views
6

Điều này thật lạ. Tôi có đoạn mã sau:'dễ bay hơi' trong chữ ký phương pháp?

class A 
{ 
    protected A clone() throws CloneNotSupportedException 
    { 
     return (A) super.clone();  
    } 
} 

khi tôi de-biên soạn bytecode của mình thông qua 'showmycode.com', nó cho tôi xem đoạn mã sau:

class A 
{ 

    A() 
    { 
    } 

    protected A clone() 
    throws clonenotsupportedexception 
    { 
     return (A)super.clone(); 
    } 

    protected volatile object clone() 
    throws clonenotsupportedexception 
    { 
     return clone(); 
    } 
} 

có nghĩa là gì cho một loại phương thức hoàn trả biến động trong phương pháp 'nhân bản' thứ hai? (Mã này được biên dịch thông qua trình biên dịch JDK 1.6 mặc định của Eclipse).

+5

Tôi nghĩ rằng câu trả lời này áp dụng ở đây: http://stackoverflow.com/questions/6651867/why-make-a-method-volatile-in-java –

+0

@bunting thx. Bạn có thể pl.đề cập đến nó trong câu trả lời của bạn để tôi có thể chấp nhận nó? – shrini1000

Trả lời

4

Mặt nạ sửa đổi cho các trường và phương thức tương tự nhưng không chính xác giống nhau. Các decompiler rất có thể sử dụng phương pháp toString đây

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/reflect/Modifier.java

nhưng những gì nó không làm là xử lý tất cả các bit

// Bits not (yet) exposed in the public API either because they 
// have different meanings for fields and methods and there is no 
// way to distinguish between the two in this class, or because 
// they are not Java programming language keywords 

gì mình không xử lý là các bit có thể có nghĩa là syntheticbridge xác định mã trình biên dịch được tạo.

Nếu volatile có nghĩa là bất cứ điều gì ở đây, điều đó có thể có nghĩa là không loại bỏ phương pháp mặc dù nó không làm gì cả.

+0

Nó không phải là một lỗi. Dường như các phương thức được tạo ra cần thiết cho generics và được chèn vào trong các lớp được biên dịch một cách âm thầm, được đánh dấu là "dễ bay hơi", ngay cả khi đây không phải là ý nghĩa chính xác của chúng. – Panayotis

1

Đó là lỗi trong trình biên dịch ngược của bạn.

volatile chỉ là công cụ sửa đổi hợp lệ cho trường.

Tôi khuyên bạn nên đọc this aricle.

+1

Tôi hiểu điều đó. Câu hỏi của tôi là: tại sao mã được giải mã có 'biến động' trong chữ ký phương thức * khi mã gốc không *? Có vẻ như chỉ có các phương pháp cầu mới có dấu hiệu này. – shrini1000

+0

@ shrini1000, cố gắng biên dịch mã bị biên dịch của bạn - bạn sẽ thấy rằng nó không biên dịch. Trong java bạn không thể đánh dấu phương thức với công cụ sửa đổi dễ bay hơi. Tôi đoán đó là lỗi của công cụ bạn sử dụng để giải mã. – aviad

4

Nó không có ý nghĩa gì cả. Nó là một lỗi trong trình biên dịch ngược. Kết thúc câu chuyện.

(Lỗi này có thể liên quan đến thực tế là các bit cờ nhất định được sử dụng trong định dạng tệp lớp là "quá tải", có nghĩa là những thứ khác nhau trong ngữ cảnh của một lớp, trường hoặc phương pháp. một số "sử dụng mới" trong các bản sửa đổi thông số JVM gần đây.)

8

Câu trả lời này đã được đề cập trong câu hỏi Why make a method volatile in java? Nhưng đây là một số thông tin khác.

Khi bạn quá tải phương thức (có thể chỉ có các phương thức chung trong lớp cha), phương pháp được đánh dấu là "bridge method". Từ java.lang.reflect.Modifier:

static final int BRIDGE = 0x00000040; 

Thật không may, đây là chút tương tự được sử dụng để đánh dấu các lĩnh vực như là volatile:

public static final int VOLATILE   = 0x00000040; 

Nếu bạn in các sửa đổi trên các phương pháp mà bạn sẽ thấy một cái gì đó như:

public volatile 

Đây là giới hạn trong phương thức Modifiers.toString(int) không biết đó là trường hay phương pháp.

public static String toString(int mod) { 
    StringBuffer sb = new StringBuffer(); 
    ... 
    if ((mod & VOLATILE) != 0) sb.append("volatile "); 
    // no mention of BRIDGE here 
    ... 
    return sb.toString().substring(0, len-1); 
} 
Các vấn đề liên quan