Java 帮助我理解指针与值的问题
我知道这是一个愚蠢的问题,但它真的困扰着我 采取以下行动:Java 帮助我理解指针与值的问题,java,pointers,Java,Pointers,我知道这是一个愚蠢的问题,但它真的困扰着我 采取以下行动: public <TParseable> LinkedList<TParseable> readAllParseable( Parseable<TParseable> parseable, boolean close) throws IOException { LinkedList<TParseable> list = new LinkedList<TPa
public <TParseable> LinkedList<TParseable> readAllParseable(
Parseable<TParseable> parseable, boolean close) throws IOException
{
LinkedList<TParseable> list = new LinkedList<TParseable>();
byte[] delim = parseable.getDelimiterValue();
boolean skipNL = parseable.skipNewLines();
while(ready())
{
byte[] data = readTo(delim);
parseable.parse(data);
System.out.println(parseable);
list.add((TParseable)parseable);
}
return list;
}
public LinkedList readAllParseable(
可解析可解析,布尔关闭)引发IOException
{
LinkedList=新建LinkedList();
字节[]delim=parseable.getDelimiterValue();
布尔值skipNL=parseable.skipNewLines();
while(ready())
{
字节[]数据=readTo(delim);
解析(数据);
System.out.println(可解析);
list.add((TParseable)可解析);
}
退货清单;
}
每次调用parseable.parse(data)
后,println语句都会输出toString()的预期值parseable
。但是,返回的列表具有正确的元素数,但它们都等于循环完成之前的最后一个可解析值
这是因为list.add(xxx)参数是通过指针而不是值传递的吗?您每次都将相同的可解析对象放入列表中。每次可解析对象解析某些数据时,都使用相同的可解析对象对其进行处理 您发布的代码中只有一个parseable
实例。当您调用add(parseable)
时,您正在向列表中的parseable
添加一个引用(“指针”在Java中并不正确)
通过重复调用它,而不更改对象parseable
所指的对象,您只需将对同一对象的更多引用添加到列表中
新对象仅由New
关键字创建。通过整个方法,对象parseable
是相同的。我假设当您调用parseable.parse(data)
时,它会更改parseable中的内部数据。由于您一直将同一个对象放在列表中,所以每次迭代都只对同一个对象进行操作。我认为您的概念问题是术语之一。如果我把“值”改为“状态”,也许会有助于澄清问题
println语句输出
应为可解析的toString()状态
每次打电话到
解析(数据)。
但是,返回的列表具有
元素数正确,但它们
都等于的最后一个状态
可在循环完成之前解析
实际上,您的程序只使用一个可解析实例,并且对该实例的方法调用正在更改其状态
这是因为list.add(xxx)
参数是通过指针传递的,而不是
而不是价值
否。这是因为实例的状态(如toString()
所示)正在更改
事实上,Java对方法和构造函数调用中的所有参数使用传递值语义,而不管类型如何。稍微令人困惑的是,在Java中传递对象/数组时传递的“值”是一个引用
编程语言支持的三种基本参数传递机制是:
- 通过值传递,复制的值可能是基元值、指针/引用值或(在某些语言中)结构化值。(在某些语言中,返回时可以将值复制回来,但这只是传递值的逻辑扩展。)
- 通过引用传递,在调用方中传递变量的地址,允许被调用方更改该变量,和/或查看其他更改变量的结果
- pass-by-name是Algol-60中使用的一种“聪明”机制,它的实现成本很高,而且对于大多数程序员来说很难有效地使用
我不会使用术语“通过指针传递”。这实际上只是说“通过指针的值传递”的另一种方式。。。如果你试图把它看成是不同的东西,你只会感到困惑。我就是这么想的,只是想核实一下。是的。它应该是一个静态方法,返回一个对象的新实例,但不幸的是,没有办法用接口或抽象方法实现这一点…这最近真的让我感到不安。如果你发现自己想在接口上使用静态方法来创建新对象,那么你需要的是工厂模式。