我对Java“所有值得通过”概念感到困惑。
请考虑以下代码:
class Test {
Integer A;
String B;
...
void SetVar(Object??? var, Object value) {
// Set A variable to the value (considering that it's possible)
}
}
我可以通过以下代码将SetVar
设置为A
并将2
设置为B
的方式对Hi
函数进行编码吗?
void Init() {
SetVar(this.A, 2);
SetVar(this.B, "Hi");
}
答案 0 :(得分:2)
是的,你可以。通过使用反射java api。
class Test{
void SetVar(Field field, Object value) throws
IllegalArgumentException,IllegalAccessException {
field.set(this, value);
}
public static void main(String[] args){
Test test =new Test();
test.SetVar(Test.class.getDeclaredField("A"), 2);
test.SetVar(Test.class.getDeclaredField("B"), "Hi");
}
}
答案 1 :(得分:2)
简而言之,将值(与=
运算符有意义)重新分配给现有引用不会更改指向原始引用的对象。
在Java中被误解的是,人们认为它们是两种类型的变量:
Java 从不使用引用。 参考这个词用词不当。
Java仅使用指针来操作对象。
为了更好地理解阴影:http://javadude.com/articles/passbyvalue.htm
关于你的情况,即使你跳过Java命名约定(但它是另一个主题),你可以通过这样做来解决你的“问题”:
void SetVar(Integer value) {
this.A = value;
}
实际上,如果您将A
作为本地参数传递(就像您所做的那样),那么这个本地参数将代表A
引用的副本,因为Java只是专注于在passed-by-value
。因此,更改它不会影响初始参考。
答案 2 :(得分:1)
一般来说,这取决于。在这种特殊情况下,A和B是不可变的,你不能。
如果你有一个带有setter的可变对象,你可以在setVar
方法中改变它的一些属性:
var.setValue(value);
但是你无法改变原始对象指向的引用(因为它已经通过值传递)。
var = someOtherObject; //no effect on the reference in the calling code
答案 3 :(得分:1)
是的,Java是按值传递的,但您还必须意识到,当您将对象传递给某个方法时,实际上是将一个引用(指针)传递给该对象。在您的情况下,两个参数A
和B
也是不可变的,这意味着您只能重新分配代表它们的局部变量,而不是替换传递给{{1}的原始对象。 }。
答案 4 :(得分:0)
void SetVar(Object??? var, Object value) {
成为
void SetVar(final Integer var, final String value) {
A=var; // use minuscule for field like a=var;
B=value; // this. is not necessary here
}
在构造函数中初始化:
Test (final Integer var, final String value){
setVar(var, value);
}
答案 5 :(得分:0)
Integer
和String
是不可变的,因此您无法在初始化后更改A
或B
的值,只需为变量指定一个新值即可。因为一旦在SetVar
内,变量var
是方法的本地变量,更改var
指向的对象不会影响外部调用者。
答案 6 :(得分:0)
你不能这样做,因为在你的例子中你传递this.A到setVar()方法,而this.A是null,所以这没用。但你可以做的就是拥有它。作为一个持有者,并将持有者传递给setVar()方法。
以下代码可以满足您的需求。它为字段a和b使用IntegerHolder和StringHolder,并在构造具有空的holder对象的类时初始化holder字段。
调用setVar()然后不设置字段a和b的值,而是设置持有者的内容。
public class Test
{
IntegerHolder a = new IntegerHolder();
StringHolder b = new StringHolder();
void setVar(IntegerHolder var, Integer value) {
var.value = value;
}
void setVar(StringHolder var, String value) {
var.value = value;
}
class IntegerHolder
{
Integer value;
}
class StringHolder
{
String value;
}
}