Student.java
class Person
{
public int age;
public String name;
public Person(int age,String name){
this.setAge(age);
this.setName(name);
}
public void info(){
System.out.println("sdflksdj");
}
public void setAge(int age){
this.age=age;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return this.age;
}
public String getName(){
return this.name;
}
}
public class Student extends Person
{
public String school;
public Student(int age,String name,String school){
super(age,name);
this.setSchool(school);
}
public void setSchool(String school){
this.school=school;
}
public String getSchool(){
return this.school;
}
}
编译:javac Student.java
分析字节码:javap -c -private Student.java
Compiled from "Student.java"
public class Student extends Person {
  public java.lang.String school;  public Student(int, java.lang.String, java.lang.String);
    Code:
       0: aload_0
       1: iload_1
       2: aload_2
       3: invokespecial #1                  // Method Person."<init>":(ILjava/la
ng/String;)V
       6: aload_0
       7: aload_3
       8: invokevirtual #2                  // Method setSchool:(Ljava/lang/Stri
ng;)V
      11: return  public void setSchool(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #3                  // Field school:Ljava/lang/String;
       5: return  public java.lang.String getSchool();
    Code:
       0: aload_0
       1: getfield      #3                  // Field school:Ljava/lang/String;
       4: areturn  public java.lang.String getName();
    Code:
       0: aload_0
       1: invokespecial #4                  // Method Person.getName:()Ljava/lan
g/String;
       4: areturn  public int getAge();
    Code:
       0: aload_0
       1: invokespecial #5                  // Method Person.getAge:()I
       4: ireturn  public void setName(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: invokespecial #6                  // Method Person.setName:(Ljava/lang
/String;)V
       5: return  public void setAge(int);
    Code:
       0: aload_0
       1: iload_1
       2: invokespecial #7                  // Method Person.setAge:(I)V
       5: return  public void info();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method Person.info:()V
       4: return
}
如果我把声明Studnet类的的public去掉
编译:javac Student.java 通过
分析字节码:javap -c -private Student
则:
Compiled from "Student.java"
class Student extends Person {
  public java.lang.String school;  public Student(int, java.lang.String, java.lang.String);
    Code:
       0: aload_0
       1: iload_1
       2: aload_2
       3: invokespecial #1                  // Method Person."<init>":(ILjava/la
ng/String;)V
       6: aload_0
       7: aload_3
       8: invokevirtual #2                  // Method setSchool:(Ljava/lang/Stri
ng;)V
      11: return  public void setSchool(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #3                  // Field school:Ljava/lang/String;
       5: return  public java.lang.String getSchool();
    Code:
       0: aload_0
       1: getfield      #3                  // Field school:Ljava/lang/String;
       4: areturn
}就去掉了一个public,怎么会有这样的区别????
很是纳闷,去掉public后,从分析的字节码来看,好像Studnet类没有继承Person类(当然是继承了)
但是没去掉public之前,明显看出是继承了Person类,希望能从根本上给解答一下。

解决方案 »

  1.   

    源代码Student.javaclass Person
    {
    public int age;
    public String name;
    public Person(int age,String name){
    this.setAge(age);
    this.setName(name);
    }
    public void info(){
    System.out.println("sdflksdj");
    }
    public void setAge(int age){
    this.age=age;
    }
    public void setName(String name){
    this.name=name;
    }
    public int getAge(){
    return this.age;
    }
    public String getName(){
    return this.name;
    }
    }
    class Student extends Person
    {
    public String school;
    public Student(int age,String name,String school){
    super(age,name);
    this.setSchool(school);
    }
    public void setSchool(String school){
    this.school=school;
    }
    public String getSchool(){
    return this.school;
    }
    }
      

  2.   

    javap -c -private Studnet以下是分析的字节码内容:(没去掉Studnet类前面的public之前)
    Compiled from "Student.java"
    public class Student extends Person {
      public java.lang.String school;  public Student(int, java.lang.String, java.lang.String);
        Code:
           0: aload_0
           1: iload_1
           2: aload_2
           3: invokespecial #1                  // Method Person."<init>":(ILjava/
    ng/String;)V
           6: aload_0
           7: aload_3
           8: invokevirtual #2                  // Method setSchool:(Ljava/lang/St
    ng;)V
          11: return  public void setSchool(java.lang.String);
        Code:
           0: aload_0
           1: aload_1
           2: putfield      #3                  // Field school:Ljava/lang/String;
           5: return  public java.lang.String getSchool();
        Code:
           0: aload_0
           1: getfield      #3                  // Field school:Ljava/lang/String;
           4: areturn  public java.lang.String getName();
        Code:
           0: aload_0
           1: invokespecial #4                  // Method Person.getName:()Ljava/l
    g/String;
           4: areturn  public int getAge();
        Code:
           0: aload_0
           1: invokespecial #5                  // Method Person.getAge:()I
           4: ireturn  public void setName(java.lang.String);
        Code:
           0: aload_0
           1: aload_1
           2: invokespecial #6                  // Method Person.setName:(Ljava/la
    /String;)V
           5: return  public void setAge(int);
        Code:
           0: aload_0
           1: iload_1
           2: invokespecial #7                  // Method Person.setAge:(I)V
           5: return  public void info();
        Code:
           0: aload_0
           1: invokespecial #8                  // Method Person.info:()V
           4: return
    }
      

  3.   

    去掉Studnet类的public之后编译成功
    用javap -c -private再次分析
    javap -c -private StudentCompiled from "Student.java"
    class Student extends Person {
      public java.lang.String school;  public Student(int, java.lang.String, java.lang.String);
        Code:
           0: aload_0
           1: iload_1
           2: aload_2
           3: invokespecial #1                  // Method Person."<init>":(ILjava/la
    ng/String;)V
           6: aload_0
           7: aload_3
           8: invokevirtual #2                  // Method setSchool:(Ljava/lang/Stri
    ng;)V
          11: return  public void setSchool(java.lang.String);
        Code:
           0: aload_0
           1: aload_1
           2: putfield      #3                  // Field school:Ljava/lang/String;
           5: return  public java.lang.String getSchool();
        Code:
           0: aload_0
           1: getfield      #3                  // Field school:Ljava/lang/String;
           4: areturn
    }
      

  4.   

    哪里看出去掉public之后不是明显继承呢,不是还是有extends吗
      

  5.   

    javap -c  Student
    试试
      

  6.   

    你理解错了 
    我的意思是说对于Student.java文件,去掉Student类前的public前后用javap分析一下出来的结果不一样,去掉后,父类的方法没有在子类中体现,我是这个意思,这个什么原因呢
      

  7.   

    要注意的重点在于:
    Person类的访问修饰为默认访问(即包内可见,等同于C++的访问修饰符friendly,由于在下的习惯问题,下面提到的friendly都是指Java的默认访问)。由于Person类本身是friendly的缘故,其定义的函数info等虽然修饰符为public,但实际的可见范围也是friendly。这时用一public的类Student去继承Person类,无意中扩大了info等函数的可见范围。因此在Student类的代码中要包含可见范围被扩大的info等函数的代码。1、将Student类也定义为friendly
    2、将Person类定义为public
    3、将info等函数定义为friendly或可见范围更小的private
    以上三种情况都不会造成函数可见范围扩大,子类Student中也不必包含父类Person中定义的函数代码了。
      

  8.   

    试了几下发现貌似必须是 继承自父类的方法访问控制符在子类中必须是public才能在javap -c -private下显示(但未找到官方文件确认)子类是package-private时,如9楼所说,父类的public方法继承到子类中合成效果不是public,所以未显示