Java 变量范围 - 复制位图?

Java variable scope - copying bitmaps?

我试图更好地理解 Java 变量范围是如何工作的,以及当我们在方法中执行类似以下操作时底层数据到底发生了什么:

this.variable = variable

这条线到底是做什么的?这是我的实际问题:

我正在加载位图以在我的 (Android) OpenGL ES 2.0 项目中用作纹理。它是这样的:

public loadBitmapsForTextures(){

    myBitmap = BitmapFactory.decodeResource(view.getResources(), R.drawable.testbmp, Options);

    myObject.setTexture(view, myBitmap);

    Log.v("NewTag","Recycled: Again: "+myBitmap);

    myBitmap.recycle(); //All done - no longer required.  But why is myBitmap still valid here?
}

在我的 Sprite class(其中 myObject 是一个对象)中,我有以下内容:

public void setTexture(GLSurfaceView view, Bitmap imgTexture){
        
        this.imgTexture=imgTexture;  //What exactly is this line doing?  Copying the actual data?  Just making another 'pointer' to the original data?

        iProgId = Utils.LoadProgram(strVShader, strFShader);
        iBaseMap = GLES20.glGetUniformLocation(iProgId, "u_baseMap");
        iPosition = GLES20.glGetAttribLocation(iProgId, "a_position");
        iTexCoords = GLES20.glGetAttribLocation(iProgId, "a_texCoords");
        //Return usable texture ID from Utils class
        texID = Utils.LoadTexture(view, imgTexture);
                    
        Log.v("NewTag","Recycled: Before: "+imgTexture);
        imgTexture.recycle();
        imgTexture=null;
        Log.v("NewTag","Recycled: After"+imgTexture);           
        
}

setTexture 方法中的日志给出了我期望的结果。第一个命名位图:

Recycled: Before: android.graphics.Bitmap@1111111

Recycled: After: null

但是,初始 loadBitmapsForTextures() 方法中的日志语句给出了一些我没有预料到的内容:

Recycled: Again: android.graphics.Bitmap@1111111

为什么我可以(貌似)再次回收此位图?我只能假设我对以下行的理解有缺陷:

this.imgTexture=imgTexture;

那么,这条线到底做了什么?据我所知,它将 class 变量应用与局部变量相同的值(已传递到方法中),但是,显然还有更多事情正在发生。它真的创建了一个全新的位图吗?如果是,为什么登录时名称相同?

此行将实例成员 imgTexture 设置为引用同一对象,该对象的引用已传递给该方法。

this.imgTexture=imgTexture;   

此行将传递给方法的引用设置为 null,这不会改变 this.imgTexture

imgTexture=null;

也许您想将其替换为

this.imgTexture=null;

如果您希望对象不再包含对该位图的引用。

除了简单的布尔值和数值之外,其他任何东西都是通过引用传递的。所以

Object o1 = new Object();

创建一个新对象并将一个名为 o1 的引用分配给内存中的区域。

Object o2 = o1;

将名为 o2 的新引用分配给内存中的同一区域。当您调用带参数的方法时,也会发生同样的事情;您正在处理同一个实体,而不是副本。