谈谈Java的对象

1. 目的

本文通过简单的示例,阐述Java中对象的概念,避免TXs犯类似的错误。


本文的代码示例均来源于实际产品的遗留代码,但抽象为更加简单易懂的例子。


2. 示例1

先看一段代码,其主要意思是替换列表中某个元素的属性。

2.1 Student.java

public class Student {
	int id;
	private String name = null;
	int score;
	
	public Student(int id, String name, int score) {
		this.id = id;
		this.name = name;
		this.score = score;
	}
	
	public int getId() {
		return id;
	}
	
	public String getName() {
		return name;
	}
	
	public int getScore() {
		return score;
	}
	
	public void setScore(int score) {
		this.score = score;
	}
	
	public String toString() {
		return "Student[id=" + id
				+ ", name=" + name
				+ ", score=" + score
				+ ", hashCode=" + hashCode()
				+ "]";
	}

}

2.2 StudentObjects.java

import java.util.ArrayList;
import java.util.List;


public class StudentObjects {
	private List<Student> students = new ArrayList<Student>();
	
	private void dumpObjects() {
		for (Student s : students) {
			System.out.println(s);
		}
	}
	
	private void addSomeObjects() {
		students.add(new Student(1, "first", 10));
		students.add(new Student(2, "second", 20));
		students.add(new Student(3, "third", 30));
	}
	
	private void updateObject() {
		int id = 2;
		for (Student s : students) {
			if (s.getId() == id) {
				Student temp = s;
				temp.setScore(200);
				students.add(students.indexOf(s), temp);
				students.remove(s);
				return;
			}
		}
	}

	private static void test() {
		StudentObjects objects = new StudentObjects();
		
		objects.addSomeObjects();
		objects.dumpObjects();
		
		objects.updateObject();
		objects.dumpObjects();
	}
	
	public static void main(String[] args) {
		test();
	}

}

2.3 运行结果

Student[id=1, name=first, score=10, hashCode=31168322]
Student[id=2, name=second, score=20, hashCode=17225372]
Student[id=3, name=third, score=30, hashCode=5433634]
Student[id=1, name=first, score=10, hashCode=31168322]
Student[id=2, name=second, score=200, hashCode=17225372]
Student[id=3, name=third, score=30, hashCode=5433634]

2.4 分析

我们要讨论的是上述代码中的updateObjects()方法。

这里的替换或更改属性的算法,是典型的对于Java对象不慎理解的情形。变量temp和s其实指向的是同一个对象,因此在列表中add&remove完全是不必要的操作。

为了更加明确说明对象的概念,我们在toString()中把hashCode也打印出来了,可以看出,temp和s其实完全是heap中的同一个对象。


2.5 改进的代码

	private void goodUpdateObject() {
		int id = 2;
		for (Student s : students) {
			if (s.getId() == id) {
				s.setScore(200);
				return;
			}
		}
	}

3. 题外话

通过本文的例子,可以发现写这个代码的TX知道的东西很多,包括add, indexOf, remove。由此说明,对相关知识点(比如List)还是做了相当的功课。但是否这样的代码就是我们提倡的呢?答案显然是否定的。

  • 我们需要的是简单的算法、简单明了的代码,越简单越好,因为代码是写给人看的,而不是计算机看的。
  • 通过复杂的算法去完成了简单的任务,是在制造问题,而不是解决问题。——因为让维护人员看着诡异。
  • 诡异的代码无形中增加了程序的运行成本,即恶化了程序的性能。现在的软件产品的规模通常都是以10KLOC为单位,在这种规模的软件中,如果处处都充斥着本文类似的编写方式,可想对产品的性能会有多大的冲击。——对于smart phone就是影响其续航能力。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值