当你需要在Java中通过引用传递给多个参数赋值时,你该怎么做?
为了将一些方法重构为更小的方法,我需要通过引用传递,因为我只能有一种返回类型。每当我需要这样做时,我都可以创建不同的返回或参数类型,但最终我会得到一堆臃肿的、看似不必要的类。
除了重新设计程序之外,最好的替代方案是什么?
编辑:其中一些可以重新设计,这就是我正在做的事情,但是,例如,在某一时刻,它是在一个巨大的集合中找到最小值和第二最小值,然后操纵它们。我想将其分为两种方法 - 一种是发现,另一种是操纵 - 但我似乎不太可能干净利落地做到这一点。
In order to refactor some methods into smaller ones, I need pass by reference, since I can only have one return type. I could create a different return or parameter type whenever I need to do this, but then I'd end up with a bunch of bloated, seemingly unnecessary classes.
What is the best alternative here, besides redesigning the program, which can't be done?
edit: some of it CAN be redesigned, and that's what I am doing, but, for example, at one point it is finding the minimum and second minimum values in a huge collection and then manipulating them. I wanted to split that into 2 methods - one finds, another manipulates - but it seems highly unlikely I'll be able to do this cleanly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您正在谈论通过所谓的输出参数“返回”多个值,就像您有时在 C 中找到的那样,这些值是通过引用传递的?
您要求提供返回单个值类的替代方案,但这确实是正确的做法。
但既然你问了,是的,你是对的,你需要做更多的工作来获得 Java 中的按引用传递语义。 Java 总是按值传递(是的,我的意思是——对象引用被传递到方法中,并且这些是按值传递的)。因此,要伪造按引用传递,如果您想以这种方式传回新的引用,您可以执行一些操作,例如传递一个对象的数组,并更改它包含的引用。
不过我认为这是非常非常规的,并且不会推荐它。通过重构获得的任何改进都会被破坏。
You are talking about "returning" multiple values by means of so-called out parameters, like you sometimes find in C, which are passed by reference?
You asked for an alternative to returning a single value class, but that is really the right thing to do.
But since you ask, yes, you're correct that you need a little more work to get pass-by-reference semantics in Java. Java is always pass-by-value (yes I mean that -- it is object references that are passed into methods, and those are passed by value). So to fake pass-by-reference, you could do something like pass an array of one Object, and change the reference it contains, if you wanted to pass back a new reference this way.
However I'd call this highly unconventional and would not recommend it. Any improvement you get by refactoring is destroyed by this.
严格来说,Java 没有按引用传递。 Java 中只有一种传递机制,那就是按值传递。
对于对象来说,传递的不是对象本身,它位于堆上。它是对按值传递的对象的引用。
这听起来可能有点挑剔,但它很重要。
我不明白这与重构有什么关系。如果您需要创建新类型只是为了返回,请务必这样做。我敢打赌,您确实没有反映当前问题的对象模型,这就是您遇到重构问题的原因。
对我来说听起来不太面向对象,尤其是在阅读了您的编辑之后。
To be strictly precise, Java does not have pass by reference. There's only one passing mechanism in Java, and that's pass by value.
In the case of objects, the thing that's being passed is not the object itself, which lives on the heap. It's the reference to the object that's passed by value.
It might sound like a nitpick, but it's an important one.
I don't see what this has to do with refactoring. If you need to create new types just to be returned, by all means do so. I'd bet that you really don't have an object model that reflects the problem at hand, which is why you have this refactoring problem.
Doesn't sound very object-oriented to me, especially after reading your edit.
您可以做一些事情,例如创建一个可以处理函数中的值的泛型类。
下面是如何使用该类从函数获取整数的示例。
它可能不是最优雅的整体解决方案,但如果您不想进行更复杂的重构,它将使您不必编写大量类。
You could do something like create a generic class that could handle out values from a function.
Here is an example of how the class could be used to get an integer from a function.
It is probably not the most elegant overall solution, but it will keep you from having to write a ton of classes if you do not want to do a more involved refactor.
将您的变量提升为实例变量,这样它们对两种方法都是可见的(毕竟您可以在对象中拥有状态)。如果它们看起来不应该属于您的对象,那么我认为您将无法绕过重新设计。
Promote your variables to instance variables, that way they'll be visible to both methods (you are allowed to have state in an object after all). If they don't look like they should belong on your object then I don't think you'll be able to get around a redesign.
由于在方法中,参数和对象的引用是按值传递的,因此您不能执行以下操作:通过
这种方式,您可以更改对象的值,而不返回不同的类型。
Since in a method, the arguments the references of objects are passed by value, couldn't you do something along the lines of:
This way, you are changing the values of the objects, without returning diverging types.
唔
数据要么属于一起,这就是您决定从单个方法返回它们的原因,要么不属于一起。如果他们这样做了,是不是一个新的班级是合适的?
作为最后的手段,你可以返回一个 Vector。
编辑
或者如果您总是有有限数量的返回项,您可以使用类似
Pair
(或定义一些此类通用元组类型)Hmm
either the data belong together, which is why you have decided to return them from a single method, or they don't. If they do, isn't a new class is appropriate?
As a last ditch you could return a Vector.
edit
or if you always had a finite number of return items you could use something like
Pair<T1,T2>
(or define some such generic tuple type)如果没有更多细节,很难给出具体的建议。但可能性包括:
将相关函数放入一个类中,并将数据成员变量。就像你的“找到并最小化两个最小的”:
如果这很尴尬,另一种可能性是创建一个类来保存你需要的值并返回它。就像:
我认为这比伪造引用传递要优越得多。但如果您真的坚持,可以通过将值放入包装器中来完成,如下所示:
为了使其干净,您需要为每个类使用单独的包装器。我想你可以制作一个 ObjectWrapper 使其通用,然后进行转换,但这变得非常混乱。
我认为您最好考虑一下数据如何关联并将其移入逻辑类。
Without more detail, it's difficult to give specific advice. But possibilities include:
Put related functions into a single class and make the data member variables. Like to take your "find and minipulate two smallest":
If that's awkward, another possibility is to create a class to hold the values you need and return that. Like:
I think this is much superior to faking out a pass-by-reference. But if you really insist, it could be done by putting the value in a wrapper, like this:
To make this clean you'd need a separate wrapper for each class. I suppose you could make an ObjectWrapper to make it generic and then cast things, but this is getting quite messy.
I think you're much better off to think of how your data relates and move it into logical classes.
仅仅因为一个方法只能有一个返回类型并不意味着该类型不能包含多于一条信息。您似乎遇到的问题类型的解决方案是声明保存多条信息的数据类型。
按照问题中的示例(“在一个巨大的集合中查找最小值和第二最小值,然后操作它们”):
您还可以很容易地重构
MinimumHolder
,以便它可以保存一个变量列表“如果您想找到两个以上的最小值,则可以使用getMinimum(intposition)
公开该最小值。Just because a method can only have one return type doesn't mean that that type can't contain more than one piece of information. The solution to the type of problem you seem to be having is to declare data types which hold multiple pieces of information.
Following the example in the question ("finding the minimum and second minimum values in a huge collection and then manipulating them"):
You could also pretty easily refactor
MinimumHolder
so that it could hold a variable list of "minimums" which were exposed with agetMinimum(int position)
if you ever wanted to find more than two minimums.