2

这是我在这里的第一个问题。我是一个补偿。英。学生和我们的老师给了我们一些问题来解决。

他基本上要求我们创建 2 classes;其中一个应该包含 2 个重载constructors和一些关于data encapsulation的方法,另一个应该是main class. 我们的工作是control使用该类中的方法“”从主类中提取第一个类。他还提到我们应该primitive在类之间传递一些和引用类型变量的值。我写了一些代码,但是StackOverflow Error在初始化有构造函数的类期间我得到了一个。据我所知,当你进行递归时会出现这个错误,但我不知道我在做什么。

这是我编写的构造函数类(对不起,我的命名不好,但由于它只是家庭作业,我没有想到我的名字):

public class ConstructorClass {

    //Fields
    private String str;
    private int integer;


    //Constructors
    public ConstructorClass(String a)   {
        str= a;
    }

    public ConstructorClass(int a)  {
        integer= a;
    }

    //Objects
    public ConstructorClass obj1= new ConstructorClass("abc");
    public ConstructorClass obj2= new ConstructorClass(1);


    //Methods
    public int getInteger() {
        return this.integer;
    }

    public String getString() {

        return this.str;
    }

    public ConstructorClass getObj1() {
        ConstructorClass obj= new ConstructorClass("");
        obj.str= obj1.str;
        return obj;
    }

    public ConstructorClass getObj2() {

        return obj2; 
    }
}

编辑:这是我得到的错误:

ConstructorClass 的线程“主”java.lang.StackOverflowError 中的异常。(ConstructorClass.java:19)

第 19 行是:

public ConstructorClass obj1= new ConstructorClass("abc");
4

5 回答 5

2

你得到这个是因为你基本上得到了以下内容:

public class ConstructorClass {
    //Objects
    public ConstructorClass obj1= new ConstructorClass("abc");
    public ConstructorClass obj2= new ConstructorClass(1);
}

这是一种隐藏的递归形式。

大致相当于写

public class ConstructorClass {
    public ConstructorClass(int a)  {
        public ConstructorClass obj1= new ConstructorClass("abc");
        public ConstructorClass obj2= new ConstructorClass(1);
        ...
    }

    ...
}

即从每个构造函数调用构造函数。

另请参阅有关初始化字段的官方 java 教程- 尽管此处未明确提及,但它所说的“实例初始化程序块”也适用于使用 final 方法初始化实例字段,这就是您在此处所做的:

Java 编译器将初始化程序块复制到每个构造函数中。

详细信息在JLS 14,第 8.3.2 章中指定。字段初始化

如果声明器用于实例变量(即非静态字段),则以下规则适用于其初始化器:

  • [...]
  • 在运行时,每次创建类的实例时都会评估初始化程序并执行分配(第 12.5 节)。

  • 于 2020-04-10T10:56:15.913 回答
    0

    这是固定代码,实现了以下更改:

    1. 从 ConstructorClass 中移除循环调用(试图实例化自身的对象方法)

    2. 在ConstructorClass中引入setInteger()setString()方法来设置其私有数据成员的值。

    3. 从MainClass实例化ConstructorClass对象

    4. MainClass调用 ConstructorClass 的setInteger ()setString()方法

    工作代码:

    // File name:  MainClass.java
    
    class ConstructorClass {
        //Fields
        private String str;
        private int integer;
    
        //Constructors
        public ConstructorClass(String a)   {
            str = a;
        }
    
        public ConstructorClass(int a)  {
            integer = a;
        }
    
    
        //Methods
        public int getInteger() {
            return this.integer;
        }
    
        public String getString() {
            return this.str;
        }
    
        public void setInteger(int a) {
            integer = a;
        }
    
        public void setString(String a) {
            str = a;
        }
    
    }
    
    public class MainClass {
    
        //Objects
        ConstructorClass obj1;
        ConstructorClass obj2;
    
        public MainClass() {
            obj1 = new ConstructorClass("abc");
            obj2 = new ConstructorClass(1);
        }
    
        public ConstructorClass getObj1() {
            ConstructorClass obj = new ConstructorClass("");
            obj.setInteger(100);
            obj.setString("Hello! How are you doing?");
            return obj;
        }
    
        public ConstructorClass getObj2() {
            return obj2;
        }
    
        public static void main(String[] args) {
            MainClass mc = new MainClass();
            System.out.println("obj1 - integer = " + mc.getObj1().getInteger());
            System.out.println("obj1 - string = " + mc.getObj1().getString());
            System.out.println("obj2 - integer = " + mc.getObj2().getInteger());
            System.out.println("obj2 - string = " + mc.getObj2().getString());
        }
    }
    

    输出:

    > javac MainClass.java
    
    > java MainClass
    obj1 - integer = 100
    obj1 - string = Hello! How are you doing?
    obj2 - integer = 1
    obj2 - string = null
    
    于 2020-04-10T11:23:47.837 回答
    0

    Stackoverflow 即将到来,因为类正在递归地实例化,部分原因是这些行

         //Objects
          public ConstructorClass obj1= new ConstructorClass("abc");
          public ConstructorClass obj2= new ConstructorClass(1);
    

    删除上面两行问题就会消失。您将得到 1 个应该很容易解决的编译问题。

    内部发生的事情是,假设从您的主类中,您尝试使用创建此类的对象

        ConstructorClass cc = new ConstructorClass("string");
    

    现在将使用第一个构造函数。然后将创建实例字段。实例字段创建也调用构造函数。构造函数将再次创建enter code here实例字段。并且这个循环继续进行,这会导致问题。

    你需要了解类是如何加载的以及它是按什么顺序创建的。如果您尝试使用实例块或静态块,它将为您增加更多的复杂性/学习。

    于 2020-04-10T11:08:21.607 回答
    0

    每当您实例化 aConstructorClass时,您也会实例化它的两个成员obj1obj2。这些成员本身就是ConstructorClasses,所以他们每个都有obj1obj2也被实例化的成员,依此类推,直到你以StackOverflowError.

    我不确定你为什么有这两个成员(即,我看不出对他们的要求),但如果你真的需要他们,你应该在不同的环境中拥有他们(例如,作为static成员,作为本地某些方法中的变量等)

    于 2020-04-10T10:56:38.763 回答
    0

    由于在类级别本身创建以下两个对象,您会收到 stackoverflow 错误:

    public ConstructorClass obj1= new ConstructorClass("abc");
    public ConstructorClass obj2= new ConstructorClass(1);
    

    以下代码可能对您有用:

    public class ConstructorClass {
    
        //Fields
        private String str;
        private int integer;
        //Constructors
        public ConstructorClass(String a)   {
            str= a;
        }
    
        public ConstructorClass(int a)  {
            integer= a;
        }
    
    
        //Methods
        public int getInteger() {
            return this.integer;
        }
    
        public String getString() {
    
            return this.str;
        }
    
        public ConstructorClass getObj1() {
            ConstructorClass obj= new ConstructorClass("");
            obj.str= new ConstructorClass("abc").str;
            return obj;
        }
    
        public ConstructorClass getObj2() {
            return new ConstructorClass(1); 
        }
    
    } 
    
    class ConstructorExample{
        public static void main(String[] args) {
            new ConstructorClass("");
        }
    }
    

    笔记:

    如果想在你的类中实现封装,请确保你有变量的 getter 和 setterstr方法integer

    于 2020-04-10T11:00:11.837 回答