2017-01-10 66 views
0

这里是阶代码阶主构造不产生场

class Dog(name:String, age:Int) { 
    println("Dog is created!") 
    def sayHello() = println(s"My name is $name, I am $age years old") 
} 

反编译,如下所述生成的类文件。

import scala.Predef.; 
import scala.StringContext; 
import scala.reflect.ScalaSignature; 
import scala.runtime.BoxesRunTime; 
@ScalaSignature(bytes="\006\001=2A!\001\002\001\023\t\031Ai\\4\013\005\r!\021\001C2iCB$XM\035\034\013\005\0251\021!B6d[2\004(\"A\004\002\007\r|Wn\001\001\024\005\001Q\001CA\006\017\033\005a!\"A\007\002\013M\034\027\r\\1\n\005=a!AB!osJ+g\r\003\005\022\001\t\005\t\025!\003\023\003\021q\027-\\3\021\005MQbB\001\013\031!\t)B\"D\001\027\025\t9\002\"\001\004=e>|GOP\005\00331\ta\001\025:fI\0264\027BA\016\035\005\031\031FO]5oO*\021\021\004\004\005\t=\001\021\t\021)A\005?\005\031\021mZ3\021\005-\001\023BA\021\r\005\rIe\016\036\005\006G\001!\t\001J\001\007y%t\027\016\036 \025\007\025:\003\006\005\002'\0015\t!\001C\003\022E\001\007!\003C\003\037E\001\007q\004C\003+\001\021\0051&\001\005tCfDU\r\0347p)\005a\003CA\006.\023\tqCB\001\003V]&$\b") 
public class Dog 
{ 
    private final String name; 

    public Dog(String name, int age) 
{ 
    Predef..MODULE$.println("Dog is created!"); 
    } 

public void sayHello() 
{ 
    Predef..MODULE$.println(new StringContext(Predef..MODULE$.wrapRefArray((Object[])new String[] { "My name is ", ", I am ", " years old" })).s(Predef..MODULE$.genericWrapArray(new Object[] { this.name, BoxesRunTime.boxToInteger(this.age) }))); 
} 
} 

只有一个字段“名称”,但没有“年龄”字段。为什么?

+0

您的IDE可以解析'this.age'吗? –

+2

你是如何反编译的? – marios

+0

你为什么看着“反编译”的东西? –

回答

1

这是奇怪的,因为当我反编译上述代码时,我得到了这个。

import scala.Predef; 
import scala.StringContext; 
import scala.collection.Seq; 
import scala.collection.mutable.WrappedArray; 
import scala.reflect.ScalaSignature; 
import scala.runtime.BoxesRunTime; 

@ScalaSignature(bytes="\u0006\u0001\u001d2A!\u0001\u0002\u0001\u000b\t\u0019Ai\\4\u000b\u0003\r\tq\u0001P3naRLhh\u0001\u0001\u0014\u0005\u00011\u0001CA\u0004\u000b\u001b\u0005A!\"A\u0005\u0002\u000bM\u001c\u0017\r\\1\n\u0005-A!AB!osJ+g\r\u0003\u0005\u000e\u0001\t\u0005\t\u0015!\u0003\u000f\u0003\u0011q\u0017-\\3\u0011\u0005=\u0011bBA\u0004\u0011\u0013\t\t\u0002\"\u0001\u0004Qe\u0016$WMZ\u0005\u0003'Q\u0011aa\u0015;sS:<'BA\t\t\u0011!1\u0002A!A!\u0002\u00139\u0012aA1hKB\u0011q\u0001G\u0005\u00033!\u00111!\u00138u\u0011\u0015Y\u0002\u0001\"\u0001\u001d\u0003\u0019a\u0014N\\5u}Q\u0019Qd\b\u0011\u0011\u0005y\u0001Q\"\u0001\u0002\t\u000b5Q\u0002\u0019\u0001\b\t\u000bYQ\u0002\u0019A\f\t\u000b\t\u0002A\u0011A\u0012\u0002\u0011M\f\u0017\u0010S3mY>$\u0012\u0001\n\t\u0003\u000f\u0015J!A\n\u0005\u0003\tUs\u0017\u000e\u001e") 
public class Dog { 
    private final String name; 
    private final int age; 

    public void sayHello() { 
     Predef..MODULE$.println((Object)new StringContext((Seq)Predef..MODULE$.wrapRefArray((Object[])new String[]{"My name is ", ", I am ", " years old"})).s((Seq)Predef..MODULE$.genericWrapArray((Object)new Object[]{this.name, BoxesRunTime.boxToInteger((int)this.age)}))); 
    } 

    public Dog(String name, int age) { 
     this.name = name; 
     this.age = age; 
     Predef..MODULE$.println((Object)"Dog is created!"); 
    } 
} 

通过查看此您可以看到,无论nameage类字段都可以与privatefinal

在构造函数中,你可以看到nameage被分配有值,然后打印语句工作中。

我从http://www.javadecompilers.com/

希望这会清除你怀疑反编译上面的代码在网上。

0

我编译/反汇编代码段下面的方式(在Mac上使用Scala 2.12.1和Java 1.8.0_112):

$ echo > Dog.scala <<EOF 
class Dog(name:String, age:Int) { 
    println("Dog is created!") 
    def sayHello() = println(s"My name is $name, I am $age years old") 
} 
EOF 
$ scalac Dog.scala && javap -private Dog.class 

这导致到下面的输出同时包含私人最终类成员为nameage

Compiled from "Dog.scala" 
public class Dog { 
    private final java.lang.String name; 
    private final int age; 
    public void sayHello(); 
    public Dog(java.lang.String, int); 
} 

你是怎么编译/反编译代码?

在你的问题你写了关于字段。其实在你的情况下,这些不是字段,它们很简单类参数。它们仅由构造函数使用。如果您明确使用val关键字,那将是一个字段。

如果你希望这些参数是通过dog.agedog.name真正场访问,写:

class Dog(val name:String, val age:Int) { 
    println("Dog is created!") 
    def sayHello() = println(s"My name is $name, I am $age years old") 
} 

正如你可以使用的情况下,类喜欢另类:

case class Dog(name:String, age:Int) { 
    println("Dog is created!") 
    def sayHello() = println(s"My name is $name, I am $age years old") 
} 

对于更多的细节请看看Functional Objects一章的编程Scala一书。

编辑:我只是试着用JD-GUI反编译相同的类文件。这将导致丢失的私人age类成员:

import scala.Predef.; 
import scala.StringContext; 
import scala.reflect.ScalaSignature; 
import scala.runtime.BoxesRunTime; 

@ScalaSignature(bytes="\006\001-2A!\001\002\001\013\t\031Ai\\4\013\003\r\tq\001P3naRLhh\001\001\024\005\0011\001CA\004\013\033\005A!\"A\005\002\013M\034\027\r\\1\n\005-A!AB!osJ+g\r\003\005\016\001\t\005\t\025!\003\017\003\021q\027-\\3\021\005=1bB\001\t\025!\t\t\002\"D\001\023\025\t\031B!\001\004=e>|GOP\005\003+!\ta\001\025:fI\0264\027BA\f\031\005\031\031FO]5oO*\021Q\003\003\005\t5\001\021\t\021)A\0057\005\031\021mZ3\021\005\035a\022BA\017\t\005\rIe\016\036\005\006?\001!\t\001I\001\007y%t\027\016\036 \025\007\005\032C\005\005\002#\0015\t!\001C\003\016=\001\007a\002C\003\033=\001\0071\004C\003'\001\021\005q%\001\005tCfDU\r\0347p)\005A\003CA\004*\023\tQ\003B\001\003V]&$\b") 
public class Dog 
{ 
    private final String name; 

    public Dog(String name, int age) 
    { 
     Predef..MODULE$.println("Dog is created!"); 
    } 

    public void sayHello() 
    { 
     Predef..MODULE$.println(new StringContext(Predef..MODULE$.wrapRefArray((Object[])new String[] { "My name is ", ", I am ", " years old" })).s(Predef..MODULE$.genericWrapArray(new Object[] { this.name, BoxesRunTime.boxToInteger(this.age) }))); 
    } 
} 

所以也许这是JD中的错误,因为javap工作。我创建了一个ticket on github。但我怀疑他们会解决这个问题。JD-GUI项目最后一次提交是在一年多以前......