参考持久性和传递可变数量的数组

时间:2011-11-17 21:08:31

标签: java arrays static polymorphism variadic-functions

下面,我编写了一些简单的代码,可以重新创建随着应用程序的增长而出现的问题。

问题陈述:
我有一个类需要用于创建多态对象,每个对象都需要可变数量的数组作为输入。因此,在我的应用程序运行期间,我可能会有两到五个这样的对象被实例化。在它们之间,这些对象可能有15个数组。更重要的是,这些数组中的一些数据在创建之后需要可以从各种不同的其他对象进行修改,而不仅仅是创建或“容纳”它们的对象。

三个问题:
1。)将一些不同的数组传递到类中最稳定/推荐的方法是什么?我在下面使用了varargs方法,但我不确定这是否是最好的方法 2。)如何避免因静态关键字引起的问题?您将看到下面Main.java中的代码抛出与静态关键字相关的错误。我犹豫是否允许该类的所有实例共享该数组的单个副本。所有这些代码都在GUI的内部框架中,我稍后可能希望允许用户创建多个内部框架,每个内部框架都有自己的所有代码实例,用于完全不同的数据集。
3。)如何在创建阵列后启用各种其他对象来编辑和操作这些数组?您可以在下面看到我将数组传递给Another.java,然后在编辑数组之前将这些数组分配给本地类变量。本地数组是否与传递给Another.java的对象相同,或者是否因创建重复数组而导致错误?

代码示例:
下面的代码示例说明了我需要做什么。

有人能告诉我下面代码的重写版本修复了这些问题吗?

此外,我非常感谢您发送的关于如何最好地解决这些问题的文章的链接。

Main.java

public class Main {
int arrayLength = 10;
double[] array1 = new double[arrayLength];
double[] array2 = new double[arrayLength];
double[] array3 = new double[arrayLength];
double[] array4 = new double[arrayLength];
double[] array5 = new double[arrayLength];

static void makeHandleArrays(){// how do I avoid static errors thrown here?
    HandleArrays firstHandleArrays = new HandleArrays();
    firstHandleArrays.arrayLength(array1);

    HandleArrays secondHandleArrays = new HandleArrays();
    secondHandleArrays.arrayLength(array1,array2,array3); //varargs approach
}

public static void main(String[] args){//how do I avoid static errors thrown here?
    makeHandleArrays();
    Another myOtherClass = new Another(array1,array2);
}}

HandleArrays.java

public class HandleArrays {//Is this varargs approach the best way to handle a variable number of arrays as inputs?
double[][] dataArrays;
int numArrays;
void arrayLength(double[] ...ds){
    dataArrays = new double[ds.length][];
    numArrays = ds.length;
    for(int i = 0;i<ds.length;i++){
        dataArrays[i]=ds[i];
    }
}
}  

EditArrays.java

public class EditArrays {
      double[] thisHereArray=new double[10];
EditArrays(double[] arrayToEdit){  
                thisHereArray=arrayToEdit;
    thisHereArray[6]=4.678;//does this edit the same object that was passed into the class?  Or did I make an error with the name change?  
}
}

Another.java

public class Another {
double[] localArray1;
double[] localArray2;

Another(double[] anArray){
    localArray1=anArray;
    EditArrays myEditArrays = new EditArrays(localArray1);// does the name change mean that this line is NOT editing the same anArray?
}
Another(double[] anArray, double[] anotherArray){
    localArray1=anArray;
    localArray2=anotherArray;
    EditArrays myEditArrays = new EditArrays(localArray1);// does the name change mean that this line is NOT editing the same anArray?
    EditArrays anotherEditArrays = new EditArrays(localArray2);// does the name change mean that this line is NOT editing the same anotherArray?
}
}  

1 个答案:

答案 0 :(得分:1)

这里似乎发生了许多不同的问题,所以我会尝试解决它们。

  • 1)'Varags'方法

您实际上并未使用varags - 您正在使用overloading。您可以简单地声明:

,而不是使用具有越来越多变量的多个方法
void methodName(dataType...variableName) {
    // method code here
}

这将为您提供输入数据类型的数组(因此,在这种情况下,您最终会得到一个数组数组)。通常,varags将在foreach循环中引用。它们使用的唯一条件是它们必须被声明为最后一个参数;重要的是要记住,实际提供它们是完全可选的。

  • 2)static关键字问题

您使用static关键字时遇到的问题是您尝试访问静态(类级)方法中的实例变量。 static方法只能访问作为输入参数一部分提供的static变量和变量。为了解决“静态错误”,您将不得不传递类的实例(通过this引用)或特定数组,或者将数组引用修改为静态:

静态参考:

public class Main {
    static double[] arr = new double[10];

    public static void main(String...args) {
        arr[0] = 5;
    }
}

传入实例引用:

public class Main {
    double[] arr = new double[10];

    static void modifyArray(double[] modArr) {
        modArr[0] = 3;
    }

    public static void main(String...args) {
        Main inst = new Main();
        modifyArray(inst.arr);
    }
}
  • 3)从外部编辑阵列

您似乎对java如何处理输入参数感到困惑 Java将所有输入参数作为pass-by-value处理,有时称为pass-a-copy。本网站的其他部分对此进行了详细介绍,因此我不打算在此处详细介绍 但是,对你的代码意味着什么:

EditArrays(double[] arrayToEdit) {
    thisHereArray = arrayToEdit;
    thisHereArray[6] = 4.678;
}

实际上修改了一个数组 - 其中有三个(或更多)引用。也就是说,thisHereArrayarrayToEdit,以及传入的任何引用(例如,来自localArray1的{​​{1}}),都指向完全相同的数组在内存中。此代码产生相同的效果:

Another

您所做的一切都是重复引用,不是实际数组。根据您的要求,这可能是好的也可能是坏的。在多线程环境中,这将导致巨大的数量(几乎无法追踪/可重现)错误。在单线程环境中,你可能没问题。

  • 提供更多反馈

在不知道您的具体要求的情况下,提供额外的反馈意见有点困难。不过,我可以给出一些一般性的建议:

  1. 仅对定义或永久性大小绑定的集合使用数组。否则,请使用EditArrays(double[] arrayToEdit) { thisHereArray = arrayToEdit; arrayToEdit[6] = 4.678; } 框架的成员。
  2. 请勿以CollectionsvariableSameTypeSameName1格式创建和命名变量。你要么拥有相同的东西(就像你在这里看到的那样),它们都应该被放入一个集合(数组),或者它们都代表不同的东西,并且应该这样命名( variableSameTypeSameName2peopleToInvitepeopleToExclude)。
  3. 执行 NOT 对构造函数内部的外部(作为参数传递)对象进行编辑。您可以传递对要编辑的对象的引用,然后调用方法进行编辑。
  4. 不要在'常规'或制作方法中使用peopleToKill(除非您正在制作控制台应用程序,我怀疑)。当你检查东西时,它适用于调试/ miscellaneuos测试。
  5. 您提到此代码正在System.out.println()中运行,但您未提供任何Swing / AWT代码。 从不将任何UI代码直接与“后端”或模型代码混合在一起(很难说出你在尝试什么,所以这可能不是问题) - 应该避免它引起的麻烦。