Java常见代码问题解析

2022-07-11 21:12:15   文档大全网     [ 字体: ] [ 阅读: ]

#文档大全网# 导语】以下是®文档大全网的小编为您整理的《Java常见代码问题解析》,欢迎阅读!
解析,常见,代码,问题,Java
Java常见代码问题解析

问题:

public class ParamaterDemo { public static void main(String[] args) { int a = 1; update(a);

System.out.println(a); Koo ko = new Koo(); update(ko);

System.out.println(ko.a); }



static void update(int a) { a++;

}

static void update(Koo ko){ ko.a++; } }

class Koo{ int a = 1; }

输出结果为12.为什么啊?



解析

1.首先,要明白这个问题的答案,需要了解call (pass) by value call (pass) by reference 的区别.简单来说:

call by value通常是复制这个parameter的值去另外一块内存里,然后传给function, 所以在method/function里边对这个变量的所有变更,实际上都是对复制过来的镜像进行操作,不会对原本的variable有任何影响.

call by reference是将parameterreference传给function,简单点理解就是直接把variable传给function.所以说这个variable的值是可以被function改变的.这个用法在c/c++中非常常,用法是&variable_name.

2.再来,Java里边,你可以很简单的理解为: Java中只有call by value, 也就是说,所以所有传给functionparameter本身都不会被改变. (这是最简单直白的理解,当然也有另一种常sun的人那边听到的说法:Javacall by value + call by reference by value)

3.那么现在的问题就是为什么第二个结果2. 首先说一下sun官方的解: 对于reference type在作为parameter/argument的时候,也是call by value, 但是在你拥有足够权限时(比方说那个变量是public, 不是final的等等各种符合的情况),可以修改这个objectfields的值(也就是属于这个object(严谨点讲是an instance of the object) 内部的变量,


在你的例子中, ko 里边的 a 就是一个field, 所以update(ko)会使ko.a变成2).

4.如果你是一个有过c/c++学习经验的人或者你以上的解释很难理解,以下这种说法或许更适合你 (当然了,这只是大多包括我在内有c经验的人的一种理解方式)

这里可以引入一个新的概念,pointer. 这是一种比较特殊的变量,它内部所储存的东西,其实只是另外一个变量的内存地址. 如果对内存没有概念,你可以把它简单理解为是风筝的线轴,虽然看它本身看不出什么端倪,但是顺着摸过去总会找到风筝,看到它是什么样子. pointer方式理解Java的人,通常会说: Type variable = new Type(); 这个过程中,最后生成的这个variable其实就是一个pointer,而不是instance本身.

Java, c/c++经验的人通常认为Javacall by value.同时,当一个变量用在储存reference type的时候,实际上储存的是它的pointer,这也一样可以解释为什么ko.a会有2个结果,因为虽然pointer被传到function里边时,本身是call by value,无法被改变.但这并不影响function本身对这个pointer指向的object的内容做任何改变. 当然,再次声明,这只是一种帮助有c/c++经验的人理解的方法. Sun本身严正声明Java里边没有pointer这个东西的存在.

5. 再来解释一下为什么说楼上所说的(或者说楼上引用的)理解略有偏差.

引用"我们上面刚学习JAVA的数据类型,则有:值类型就是按值传递的,而引用类型是按引用传递的" 这句话很明显的有两点错误. 第一点,如果我上面所说的,Java是没有call by reference.

第二点,暂且假设Java里边是有call by reference, 这句话依然不成立. Java中的变量有两种类型: primitive types reference type.

primitive type包括byte, short, int, long, char, boolean, floatdouble.

而这8种之外的所有的,都是reference type.

下面是一段对你的贴上来的code的一点延伸,希望可以帮助你更好的理解Java中的argument / parameter到底是如何运作的. public class Test {

public static void main(String[] args) { int a = 1;

Koo koo = new Koo(); Object o = new Integer(1); Koo newKoo = new Koo(); update(a); update(koo); update(o);

update(newKoo); newUpdate(newKoo); System.out.println(a); System.out.println(koo.a); System.out.println(o);

System.out.println(newKoo.a); }

static void update(int a) { a++; }

static void update(Koo koo) {


koo.a++;

}

static void update(Object o) {

o = (int) (Integer.parseInt(o.toString()) + 1); }



static void newUpdate(Koo koo) { koo = new Koo(); } }

class Koo { int a = 1; } /*

o = (int) (Integer.parseInt(o.toString()) + 1); 这一行中的(int)纯粹是多余的,是否有这个castingcode本身没有任何影响. 如果你高兴也可以用 o = new Integer(Integer.parseInt(o.toString()) + 1); 或者干脆

o = Integer.parseInt(o.toString()) + 1;

*/

以上这些code运行之后会得到1 2 1 2的结果. 后面两个结果可以很好的说明, 即使对objects (reference type variables) 来看, Java应用的也并不是call by reference. 否则的,以上code运行结果应该是1 2 2 1

你可以真正理这个新的例子,1212这个结果原因,而对Javaarguments有一个系统全面的认识.

图片是相关资料的链接,知道里貌似不能加网址





更多解答尽在上海青大实训


本文来源:https://www.wddqxz.cn/564e5ce6aeaad1f346933fa0.html

相关推荐