Java中的别名(aliasing)问题

赋值动作是以'='运算符为之。赋值(指派)的意义是取得运算符右边的值,将该值复制到运算符的左边。右值可以是认识常量、变量,或有能力产生数值的表达式,左值则必须是个明确的、具名的变量。

基本型别的赋值动作相当直觉,因为基本型别存储的是实际数值,而非object reference.当你进行基本型别的赋值动作时,会将某值赋值到另一个值身上。例如,对基本型别写下A=B,B的内容便会被复制给A.如果你接着修改A值,B当然不会被波及。身为程序员的你,在大多数情况下都会很自然地这么预期。

但当你操作某个对象时,你所操作的其实是它的reference.所以当你“将某个对象指派给另一个对象”,实际上是将其reference从某处赋值到另一处。这意味,如果对两个对象写下C=D这样地式子,会造成C和D都指向原先D所指地对象。以下地例子用来说明这个现象。

class Number{

int i;

}

public class Assignment{

public static void main(String[] args){

Number n1= new Number();

Number n2 =new Number();

n1.i = 9;

n2.i = 47;

System.out.println("1:n1.i  " +n1.i+  ", n2.i:  " + n2.i);

n1= n2;

System.out.println("2:n1.i  " +n1.i+  ", n2.i:  " + n2.i);

n1.i =27;

System.out.println("3:n1.i  " +n1.i+  ", n2.i:  " + n2.i);

}

}

Number class十分单纯。它的两个实体(n1和n2)在main()中产生出来。每个Number实体内的i都被赋予不同之值,然后n2被指派给n1,然后n1的内容被改变。在许多程序语言中,你会预期n1和n2始终都是独立而互不干扰,但因为这里所指派的仍是reference,所以你看到的输出结果是:

1: n1.i: 9 , n2.i: 47

2: n1.i: 47, n2.i: 47

3: n1.i: 27, n2.i: 27

具体的过程是这样的在Assignment类中的创建了Number类的对象并分配了内存空间,一个叫n1的引用指向了它,并且n1.i=9;而一个叫n2的引用指向了另一个新创建的Number类的对象,n2.i =47。所以第一次打印出来的是  1: n1.i: 9 , n2.i: 47

接下来n1 = n2;这个过程就是将n2指派给n1,必须要注意。这时我们操作是它们的reference,而并不是说将某个对象指派给另一个对象。结果就造成n1这个引用指向了n2引用所指向的那个对象。深入一下:那n1原先引用的对象哪里去了?它被当成垃圾被清理掉了。回到上面这个话题,结果也就造成了n1和n2同时指向了一个对象所以结果输出为 2: n1.i: 47, n2.i: 47;

第三步,n1.i =27 也就是说将n1和n2同时指向的那个对象里面的i值改成了27,那么结果很自然输出

3: n1.i: 27, n2.i: 27

另外在调用函数时也会发生别名(aliasing)问题

class Letter{

char c;

}

public class PassObject{

static void f(Letter y){

y.c='z';

}

public static void main(String[] args){

Leter x =new Letter();

x.c= 'a';

System.out.println(" 1:x.c: " + x.c);

f(x);

System.out.println(" 2:x.c: " + x.c);

}

}

在许多程序语言中,f()会在函数范围之内为其引数Letter y制作一份副本。但因为现在传入的其实是一个reference,所以这一行:

y.c ='z';

实际上会更动到f()范围外的那个原本对象。程序结果说明了这一点:

1: x.c: a

2: x.c: z

Java实现图片放大可以使用Java的图形库和图像处理类来实现。下面是一个简单的示例代码: ```java import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.io.File; import java.io.IOException; public class ImageZoom { public static void main(String[] args) { try { // 读取原始图片 BufferedImage originalImage = ImageIO.read(new File("path/to/original/image.jpg")); // 设置放大倍数 int zoomFactor = 2; // 计算放大后的图片尺寸 int zoomedWidth = originalImage.getWidth() * zoomFactor; int zoomedHeight = originalImage.getHeight() * zoomFactor; // 创建放大后的图片 BufferedImage zoomedImage = new BufferedImage(zoomedWidth, zoomedHeight, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics2D g2 = zoomedImage.createGraphics(); // 设置抗锯齿和插值模式 g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 绘制放大后的图片 g2.drawImage(originalImage, 0, 0, zoomedWidth, zoomedHeight, null); g2.dispose(); // 保存放大后的图片 ImageIO.write(zoomedImage, "jpg", new File("path/to/zoomed/image.jpg")); System.out.println("图片放大完成。"); } catch (IOException e) { e.printStackTrace(); } } } ``` 以上代码读取原始图片,然后根据设定的放大倍数计算出放大后的尺寸,创建一个新的`BufferedImage`对象,使用`Graphics2D`绘制放大后的图片,最后保存到指定路径。你只需要将`"path/to/original/image.jpg"`和`"path/to/zoomed/image.jpg"`替换为实际的图片路径即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值