引用持久性和传递可变数量的数组
下面,我编写了简单的代码,重新创建了随着我的应用程序的增长而出现的问题。
问题陈述:
我有一个类需要用于创建多态对象,每个多态对象都需要可变数量的数组作为输入。因此,在我的应用程序运行期间,我可能会实例化两到五个这样的对象。这些对象可能有 15 个数组。更重要的是,其中一些数组在创建后需要可以从各种不同的其他对象进行修改,而不仅仅是创建或“容纳”它们的对象。
三个问题:
1.) 将多个不同数组传递到一个类中最稳定/推荐的方法是什么?我在下面使用了可变参数方法,但不确定这是否是最好的方法。
2.) 如何避免 static 关键字带来的问题?您将看到下面 Main.java 中的代码抛出与 static 关键字相关的错误。我犹豫是否允许该类的所有实例共享该数组的单个副本。所有这些代码都位于 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?
}
}
Below, I have written simple code that re-creates problems that have emerged as my application is growing.
Problem Statement:
I have a class that needs to be used to create polymorphic objects which each require a variable number of arrays as input. So I might have two to five of these objects instantiated throughout the time my app is running. And between them, these objects might have 15 arrays. What's more, some of these arrays need to be modifyable from a variety of different, other objects after they are created, not just by the objects that created or "house" them.
Three Questions:
1.) What is the most stable/recommended way of passing a number of different arrays into a class? I have used a varargs approach below, but am not sure if this is the best way.
2.) How can I avoid problems due to the static key word? You will see that the code in Main.java below throws errors related to the static key word. I hesitate to allow all instances of the class to share a single copy of the array. All of this code is in an internal frame in the GUI, and I may later want to allow the user to create multiple internal frames, each with their own instances of all this code for completely different data sets.
3.) How can I enable various other objects to edit and otherwise manipulate these arrays after the arrays have been created? You can see below that I am passing arrays to Another.java, which then assigns those arrays to local class variables before editing the array. Is the local array the same object as was passed into Another.java, or have I made an error by creating duplicate arrays?
Code Samples:
The code samples below to illustrate what I need to do.
Can anyone show me a re-written version of the code below that fixes these problems?
Also, I would very much appreciate any links you can send to articles about how these problems are best addressed.
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?
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里似乎存在许多不同的问题,所以我将尝试解决它们。
您实际上并没有使用
varags
- 您正在使用重载
。 而不是使用多个方法来增加变量数量。您可以简单地声明:这将为您提供一个输入数据类型的数组(因此,在本例中,您最终会得到一个数组的数组), 通常,变量会在
foreach
循环中被引用。使用它们的唯一条件是必须将它们声明为最后一个参数;同样重要的是要记住,实际提供它们是完全可选的。static
关键字问题static
关键字所面临的问题是您试图访问 实例 内的实例变量。 >静态(类级)方法。static
方法只能访问static
变量以及作为输入参数的一部分提供的变量。为了解决“静态错误”,您必须传递类的实例(通过this
引用)或特定数组,或者修改数组引用静态:静态引用:
传入实例引用:
您似乎对 java 如何处理输入参数有些困惑。
Java 将所有输入参数处理为按值传递,有时称为传递副本。本网站其他地方对此进行了详细介绍,因此我不打算在这里详细介绍所有内容。
不过,这对您的代码意味着:
实际上修改一个数组 - 其中有三个(或更多)引用。也就是说,
thisHereArray
和arrayToEdit
,以及传递的任何引用(例如,来自Another
的localArray1
)其中,全部都指向内存中完全相同的数组。此代码产生相同的效果:您所做的只是复制引用,而不是实际的数组。根据您的要求,这可能是好是坏。在多线程环境中,这将导致大量(几乎无法追踪/可重现)错误。在单线程环境中,您可能没问题。
在不知道您的确切要求的情况下,提供额外的反馈有点困难。不过,我可以给出一些一般性建议:
Collections
框架的成员。variableSameTypeSameName1
、variableSameTypeSameName2
格式创建和命名变量。您要么拥有相同事物的集合(就像您在这里看到的那样),并且它们应该全部放入集合(数组)中,要么它们都代表不同事物,并且应该这样命名(peopleToInvite
、peopleToExclude
、peopleToKill
)。System.out.println()
(除非您正在制作控制台应用程序,我对此表示怀疑)。当您检查内容时,它非常适合调试/杂项测试。There seem to be a number of different concerns happening here, so I'll try to address them.
You're not actually using
varags
- you're usingoverloading
. Rather than having multiple methods with increasing numbers of variables, you can simple declare:Which will give you an array of the input data type (so, you'll end up with an array of arrays, in this case). Oftentimes, the varags will be referenced in a
foreach
loop. The only condition on their use is that they have to be declared as the last parameter; it will also be important to remember that actually providing them is completely optional.static
keyword issuesThe issue you're facing with the
static
keyword is that you're attempting to access instance variables inside a static (class-level) method.static
methods can only accessstatic
variables and variables they were provided as part of the input parameters. In order to get around the 'static errors', you're going to have to pass either the instance of the class in (via athis
reference), or a specific array, or modify the array reference to be static:Static references:
Passing in instance reference:
You seem to have some confusion over how java handles input parameters.
Java handles all input parameters as pass-by-value, sometimes known as pass-a-copy. This is covered in detail elsewhere on this site, so I'm not going to go through all of it here.
What it means for your code, though, is this:
actually modifies one array - to which there are three (or more) references. That is,
thisHereArray
, andarrayToEdit
, as well as whatever reference (say,localArray1
fromAnother
) was passed in, all point to the exact same array in memory. This code produces an equivalent effect:All you've done is duplicated the references, not the actual array. Depending on your requirements, this could be good or bad. In a multithreaded environment, this will cause a huge number of (nearly untraceable/reproducable) errors. In a single-threaded environment, you're probably fine.
Without knowing your exact requirements, it's a little hard to give additional feedback. I can give some general recommendations, though:
Collections
framework.variableSameTypeSameName1
,variableSameTypeSameName2
. You either have a collection of the same things (like you appear to have here) and they should all be put into a collection (array), or they all represent different things and should be named as such (peopleToInvite
,peopleToExclude
,peopleToKill
).System.out.println()
inside of 'regular' or production methods (unless you're making a console application, which I doubt). It's fine for debugging/miscellaneuos testing when you're checking things.an internal frame in the GUI
, although you don't provide any Swing/AWT code. Never mix any UI code with 'backend' or model code directly (it's hard to tell what you're attempting, so this may not be an issue) - the headaches it causes should be avoided.