【问题标题】:Why are my constructor arguments not passed?为什么我的构造函数参数没有传递?
【发布时间】:2018-04-20 06:42:04
【问题描述】:

这是我的课。在底部的 main 方法中,我将构造函数中的两个参数(int numTriangles,double radius)作为 (8,1) 传递。在顶部半径和 numTriangles 声明的变量应该假定这些值,因为我的构造函数分配它们然后运行计算。但是,当 twoTheta 被计算为 numTriangles 在这一点上为零时,我得到除以零的错误。为什么会这样,我该如何解决?谢谢。

package Triangles;

public class Triangles {

    double radius;
    int numTriangles;
    double twoTheta = 360/numTriangles;
    double theta = twoTheta / 2;
    double base;
    double height;
    double result;
    double halfTriangleArea;
    double triangleArea;
    double area;

    public Triangles(int numTriangles, double radius) {
        this.numTriangles = numTriangles;
        this.radius = radius;
        runCalculation();
    }

    // My methods

    public double calculateBase() { // SOH
        double thetaToRadians = Math.toRadians(theta);
        double base = Math.sin(thetaToRadians) / radius;
        return base;
    }

    public double calculateHeight() { // CAH
        double thetaToRadians = Math.toRadians(theta);
        double height = Math.cos(thetaToRadians) / radius;
        return height;
    }

    public double checkPythag(double base, double height) {
        double a = base;
        double b = height;
        double result = Math.sqrt(a*a + b*b);
        return result;
    }

    public double calculateArea(double base, double height) {
        double halfTriangleArea = (0.5) * base * height;
        return halfTriangleArea;
    }

    public double runCalculation() {
        base = calculateBase();
        height = calculateHeight();
        result = checkPythag(base, height);
        halfTriangleArea = calculateArea(base, height); 
        triangleArea = 2 * halfTriangleArea;
        // C = Pi * D = Pi * 2 * r
        // A = Pi * r.^2
        area = numTriangles * triangleArea;
        // Substitute Pi for X
        // area = X * r.^2
        // if r is 1
        // area = X
        return area;
    }

    // Runnable

    public static void main(String[] args) { // create an instance of class to run in main
        Triangles triangles = new Triangles(8, 1);
        System.out.println("radius: " + triangles.radius);
        System.out.println("numTriangles: " + triangles.numTriangles);
        System.out.println("twoTheta " + triangles.twoTheta);
        System.out.println("theta " + triangles.theta);
        System.out.println("base: " + triangles.base);
        System.out.println("height: " + triangles.height);
        System.out.println("checkPythag " + triangles.result + " | " + triangles.radius);
        System.out.println("halfTriangleArea: " + triangles.halfTriangleArea);
        System.out.println("triangleArea: " + triangles.triangleArea);
        System.out.println("Approximation of Pi by triangles: " + triangles.area);
    }   
}

【问题讨论】:

  • 在初始化 numTriangles 后分配 twoTheta = 360/numTriangles
  • 哇,感谢您的及时回复。所有好的信息,我已经改变了,它现在正在工作,只是为了它的完整性而接受答案@Moskal。

标签: java variables constructor zero


【解决方案1】:

正如多个答案所指出的,twoTheta(以及theta)在调用构造函数之前被初始化,因此出现错误。

我建议你在构造函数内部初始化twoThetatheta

 public Triangles(int numTriangles, double radius) {
    this.numTriangles = numTriangles;
    this.radius = radius;
    //Initialize twoTheta
    this.twoTheta = 360/this.numTriangles;
    this.theta = this.twoTheta/2;
    runCalculation();
}

【讨论】:

  • 依赖twoThetatheta的初始化也一样
  • 花了一段时间才注意到这一点。已更正。
【解决方案2】:

您从构造函数调用runCalculation() - 此时twoTheta 已为其分配了默认值(对于基元,该默认值甚至在调用构造函数之前就已分配)。有两种简单的方法可以解决您的问题:

  1. 您应该从构造函数外部调用runCalculation(),以确保所有字段都初始化为默认值以外的值(为您指定的值)

  2. 您可以在构造函数中初始化twoThetatheta调用runCalculation()


如果您想使用第一个选项 - 像这样更改您的 main 方法以查看您期望的结果:

public static void main(String[] args) {
    Triangles triangles = new Triangles(8, 1);
    triangles.runCalculation();
    ...
}

您还应该从构造函数的主体中删除对runCalculation() 的调用。


如果您选择第二种解决问题的方法,只需在构造函数主体中的runCalculation() 之前初始化thetatwoTheta

public Triangles(int numTriangles, double radius) {
    this.numTriangles = numTriangles;
    this.radius = radius;
    this.twoTheta = 360/this.numTriangles;
    this.theta = this.twoTheta/2;
    runCalculation();
} 

您可能想查看官方 Java 教程中的 here 以查看分配给原始类型的默认值列表并阅读更多相关信息(顺便说一下,对象默认分配给 null)。

【讨论】:

    【解决方案3】:

    类属性在构造函数被调用之前被初始化。
    因此,numTriangles 属性首先设置为 0。然后执行 double twoTheta = 360/numTriangles;
    之后调用构造函数。
    这就是你得到错误的原因。

    因此,不要直接初始化属性twoThetatheta,而是设置numTrianglesradius属性后让构造函数处理。

    【讨论】:

      【解决方案4】:

      致电runCalculation();

      之后

      Triangles triangles = new Triangles(8, 1);
      

      在您的 main 方法中。

      让构造函数完成。

      【讨论】:

        【解决方案5】:

        因为这些定义是在类的创建而不是对象的实例化时执行的。此外,当您声明但不指定 radius 或 numTriangles 时,将使用 默认值 0。对于任何基本类型(double、int、float、...),默认值为 0,对于任何其他类型(String、Triangle、...),默认值为 null。

        您应该只在类中声明它们并在构造函数中分配它们。

        double radius;
        int numTriangles;
        double twoTheta;
        
        public Triangle(double radius, int numTriangles) {
            this.radius = radius;
            this.numTriangles = numTriangles;
            this.twoTheta = 360 / numTriangles;
        }
        

        【讨论】:

          【解决方案6】:

          您可以像这样更改代码以避免错误。

          public Triangles(int numTriangles, double radius) {
                  this.numTriangles = numTriangles;
                  this.radius = radius;           
                  initialize();
                  runCalculation();
              }
          
              private void initialize()
              {
                twoTheta = 360/numTriangles;
                theta = twoTheta / 2;      
              }
          

          【讨论】:

          • 你不认为initialize()应该在runCalculation()之前调用以避免错误吗?
          • 运行计算不使用这些变量。
          • runCalculation 调用,例如,calculateBase()calculateBase()使用Math.toRadians(theta)theta使用twoTheta,默认为0,因为你在runCalculation()之后调用initialize()
          猜你喜欢
          • 2020-01-16
          • 2014-06-18
          • 2011-05-18
          • 1970-01-01
          • 1970-01-01
          • 2011-10-09
          • 1970-01-01
          • 2018-09-12
          • 1970-01-01
          相关资源
          最近更新 更多