【问题标题】:Java pass by value or by reference? [duplicate]Java按值传递还是按引用传递? [复制]
【发布时间】:2013-01-21 23:53:03
【问题描述】:

我进行了 3 次测试以检查位图是按值传递还是按引用传递,但在运行以下代码后感到困惑:

public class MainActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    V v = new V(this);
    setContentView(v);
}

class V extends View{
    Bitmap b1;
    Bitmap b2;

    public V(Context context) {
        super(context);
        //load bitmap1
        InputStream is = getResources().openRawResource(R.drawable.missu);
        b1 = BitmapFactory.decodeStream(is);
        //testing start
        b2 = b1;
        //b1 = null; 
        //1.test if b1 and b2 are different instances
        if(b2 == null){
            Log.d("","b2 is null");
        }
        else{
            Log.d("","b2 still hv thing");
        }
        //2.test if b2 is pass by ref or value
        test(b2);
        if(b2 == null){
            Log.d("","b2 is null00");
        }
        else{ 
            Log.d("","b2 still hv thing00");
        }
                    //3.want to further confirm test2
        b2 = b2.copy(Config.ARGB_8888, true);
                    settpixel(b2); 
        if(b2.getPixel(1, 1) == Color.argb(255,255, 255, 255)){
            Log.d("","b2(1,1) is 255");
        }
        else{
            Log.d("","b2(1,1) is not 255");
        }
    }

    void test(Bitmap b){
        b = null;
    }
    void settpixel(Bitmap b){
        b.setPixel(1, 1, Color.argb(255,255, 255, 255));
    }
}}

结果:

  • b2 还是 hv 的东西

  • b2 仍然 hv thing00

  • b2(1,1) 是 255

问题是测试 2 和 3 相互矛盾。 test2 表明 b2 是按值传递的,因为 b2 没有变为空。但是如果位图是按值传递的,那么在 test3 中,setPixel() 应该在 b2(函数范围内的那个)的副本上工作,但是为什么 b2(外部范围)会改变它的像素值? p.s.加载的位图是深红色的。

【问题讨论】:

标签: java function parameter-passing


【解决方案1】:

这与 Java 的工作方式有关,而不是 Android 或 Bitmap 的工作方式。 Java 通过值传递引用。更详尽的解释可以在http://www.javaworld.com/javaqa/2000-05/03-qa-0526-pass.html

找到

【讨论】:

    【解决方案2】:

    JAVA 总是通过价值传递

    每次将变量传递给 java 的函数时,您都在复制其引用,而当您从 java return 中的函数获得结果时,它是对象引用的新副本。

    下面是您的test() 函数如何工作的分步说明:

    • 当你通过 b2 throw 调用 test(b2);您将获得对 b2 对象 b 的新引用。
    • 然后将该引用设置为空。您不会影响超出范围的引用,因为您无论如何都无法访问它。

    希望对您有所帮助。请看一下这个详细的问题:

    Is Java "pass-by-reference" or "pass-by-value"?

    【讨论】:

    • 这个描述有点误导。听起来您是在说您获得了整个 Bitmap 的副本,而您真正获得的是对 Bitmap 对象的引用的副本。
    • 我想我明白了。调用 settpixel() 时,新的 ref。仍然链接到我的外部范围 b2 ,所以 .setpixel 会影响外部范围 b2。但是在调用 test() 时,我只是将参数 b2 链接到 null 的地址,因此对参数 b2 的任何更改都不会影响外部范围 b2,因为参数不再链接到外部 b2。我说的对吗?
    猜你喜欢
    • 2016-11-28
    相关资源
    最近更新 更多