Getter和Setter是什么?有什么作用?实现多种数据类型的Getter、Setter方法?实现Getter、Setter的常见的错误?

您所在的位置:网站首页 二维码的制作方式是什么意思啊 Getter和Setter是什么?有什么作用?实现多种数据类型的Getter、Setter方法?实现Getter、Setter的常见的错误?

Getter和Setter是什么?有什么作用?实现多种数据类型的Getter、Setter方法?实现Getter、Setter的常见的错误?

2024-02-28 00:19| 来源: 网络整理| 查看: 265

什么是Getter、Setter package Bean; public class SimpleGetterAndSetter { private int number; public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } }

因为number变量是私有的,所以外部类不能直接访问到这个变量 相反,外部代码必须调用getter getNumber()和setter setNumber()才能读取或更新变量

因此,setter是一种更新变量值的方法。Getter是一种读取变量值的方法。 Getter和setter在Java中也称为访问器和更改器。

为什么要使用getter和setter?

通过使用getter和setter,程序员可以控制如何以正确的方式访问和更新他的重要变量,例如在指定范围内更改变量的值。 考虑以下setter方法的代码:

public void setNumber(int number) { //如果设置的参数不满足条件就抛出异常 if (number 100) { throw new IllegalArgumentException(); } this.number = number; }

假设可以直接更新变量number,则调用者可以为其设置任意值! 使用getter setter可以对变量的读取和设置做出控制,假如直接访问变量,无法对读取和设置做出限制

在这里插入图片描述

getter和setter的命名约定(略) 实现getter和setter时的常见错误

错误1:没有使用受限的访问修饰符

变量firstName声明为public,因此可以直接使用点(.)运算符对其进行访问,从而使setter和getter无效。 这种情况的解决方法是使用更多受限制的访问修饰符,例如protected和private

错误2:直接在setter中分配对象引用 一旦在封装器之外修改了对象引用就会破坏封装

package Bean; public class SimpleGetterAndSetter { private int[] scores; // 将变量直接赋值给对象引用 public void setScores(int[] scores) { this.scores = scores; } public void displayScores() { for (int i = 0; i SimpleGetterAndSetter simpleGetterAndSetter = new SimpleGetterAndSetter(); int[] myScores = {5, 5, 4, 3, 2, 4}; simpleGetterAndSetter.setScores(myScores); simpleGetterAndSetter.displayScores(); myScores[1] = 1; simpleGetterAndSetter.displayScores(); } }

通过第4行myScores[1] = 1;的分配,您可以意识到2nd元素的值从5更改为1。这有什么关系? 好吧,这意味着可以在设置器方法的范围之外修改数据,这会破坏设置器的封装目的。 为什么会这样呢? 让我们再次看一下上面的setScores()方法,可以发现在setter方法 中修改的对象就是当前对象的数据,所以通过修改传递的参数就修改了对象的数据,破坏了封装的目的

setScores方法中,成员变量scores直接分配给方法的参数变量scores。 这意味着两个变量都引用内存中的同一对象-myScores数组对象,因此,对实参和形参进行的更改实际上是在同一对象上进行的。所以一旦修改了传递进的参数的值,就等于修改了Setter方法中设置的值,破坏了封装

在Setter中将新对象赋值给当前对象加强封装

package Bean; public class SimpleGetterAndSetter { private int[] scores; // 将变量直接赋值给对象引用 // public void setScores(int[] scores) { // this.scores = scores; // } public void setScores(int[] scores) { // 创建一个新的数组对象 this.scores = new int[scores.length]; // 把数组参数的值逐个的复制到新创建的数组中去,这样,两个数组就相互独立,互不影响 System.arraycopy(scores, 0, this.scores, 0, scores.length); } public void displayScores() { for (int i = 0; i SimpleGetterAndSetter simpleGetterAndSetter = new SimpleGetterAndSetter(); int[] myScores = {5, 5, 4, 3, 2, 4}; simpleGetterAndSetter.setScores(myScores); simpleGetterAndSetter.displayScores(); myScores[1] = 1; simpleGetterAndSetter.displayScores(); } }

Attention!!!So, the rule of thumb is, if you pass an object reference into a setter method, then don’t copy that reference into the internal variable directly. Instead, you should find some ways to copy values of the passed object into the internal object, like we have copied elements from one array to another using System.arraycopy() method.

错误3:直接在getter中返回对象引用

package Bean; public class SimpleGetterAndSetter { private int[] scores; // 将变量直接赋值给对象引用 // public void setScores(int[] scores) { // this.scores = scores; // } public void setScores(int[] scores) { // 创建一个新的数组对象 this.scores = new int[scores.length]; // 把数组参数的值逐个的复制到新创建的数组中去,这样,两个数组就相互独立,互不影响 System.arraycopy(scores, 0, this.scores, 0, scores.length); } public void displayScores() { for (int i = 0; i return this.scores; } public static void main(String[] args) { SimpleGetterAndSetter simpleGetterAndSetter = new SimpleGetterAndSetter(); int[] myScores = {5, 5, 4, 3, 2, 4}; // 传递参数数据 simpleGetterAndSetter.setScores(myScores); // 查看传递的数据 simpleGetterAndSetter.displayScores(); // 通过getter方法获取数据 直接返回对象引用 int[] copyScore = simpleGetterAndSetter.getScores(); // 更改获取到的对象引用数据 copyScore[1] = 1; // 重新展示数据,再次展示的数据与第一次传递的数据出现变化,直接返回对象引用破坏了封装 simpleGetterAndSetter.displayScores(); } }

在访问器中返回对象的副本加强封装

public int[] getScores() { int[] copy = new int[this.scores.length]; System.arraycopy(this.scores, 0, copy, 0, copy.length); return copy; } 为原始类型实现getter和setter方法

使用基元类型(int,float,double,boolean,char…),您可以直接在setter / getter中自由分配/返回值,因为Java将一个基元的值复制到了另一个而不是复制对象引用。 因此,可以避免直接返回对象引用和直接赋值对象引用所导致的错误。 例如,以下代码是安全的,因为setter和getter涉及到的是float的原始类型:

private float amount; public void setAmount() { this.amount = amount; } public float getAmount() { return this.amount; } 实现常见对象类型的getter和setter方法

字符串对象的获取器和设置器 String是一种对象类型,但是它是不可变的,这意味着一旦创建了String对象,就不能更改其String文字。 换句话说,对该String对象的每次更改都会导致创建一个新的String对象。 因此,像原始类型一样,您可以安全地为String变量实现getter和setter,如下所示:

private String address; public void setAddress(String address) { this.address = address; } public String getAddress() { return this.address; }

日期对象的获取器和设置器 The java.util.Date class implements clone() method from the Object class. The method clone() returns a copy of the object, so we can use it for the getter and setter, like the following example:

private Date birthdate; public void setBirthdate(Date birthdate) { this.birthdate = (Date) birthdate.clone(); } public Date getBirthdate() { return (Date) this.birthdate.clone(); } 实现集合类型的getter和setter

String集合封装的错误示范

package Bean; import java.util.ArrayList; import java.util.List; public class SimpleGetterAndSetter { private List listTitles; public void setListTitles(List titles) { this.listTitles = titles; } public List getListTitles() { return this.listTitles; } public static void main(String[] args) { List list = new ArrayList(); list.add("Name"); list.add("Address"); list.add("Email"); list.add("Job"); SimpleGetterAndSetter simpleGetterAndSetter = new SimpleGetterAndSetter(); simpleGetterAndSetter.setListTitles(list); System.out.println("Titles 1:" + list); list.set(2, "Habilitation"); List list1 = simpleGetterAndSetter.getListTitles(); System.out.println("Titles 2:" + list1); list1.set(0, "Full name"); List list2 = simpleGetterAndSetter.getListTitles(); System.out.println("Titles 3:" + list2); } }

That means the collection can be modified from code outside of the getter and setter. For a collection of Strings, one solution is to use the constructor that takes another collection as argument, for example we can change code of the above getter and setter as follows:

String集合的正确封装

private List listTitles; public void setListTitles(List titles) { // this.listTitles = titles; this.listTitles = new ArrayList(titles); } public List getListTitles() { // return this.listTitles; return new ArrayList(this.listTitles); }

NOTE: The constructor approach above is only working with collections of Strings, but it will not work for collections objects. Consider the following example for a collection of Person object:

对象集合类型封装的错误示范 使用封装String集合的方式封装对象集合没有用,因为String集合中的String是不变对象,如果是对象集合就不能使用String集合的封装方式

package Bean; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; public class CollectionGetterSetterObject { private List listPeople; public void setListPeople(List listPeople) { this.listPeople = new ArrayList(listPeople); } public List getListPeople() { return new ArrayList(this.listPeople); } public static void main(String[] args) { CollectionGetterSetterObject collectionGetterSetterObject = new CollectionGetterSetterObject(); List list = new ArrayList(); list.add(new Person("zhandonghong")); list.add(new Person("jay")); list.add(new Person("vae")); list.add(new Person("eason")); collectionGetterSetterObject.setListPeople(list); System.out.println("List 1:" + list); list.get(2).setName("xusong"); List list1 = collectionGetterSetterObject.getListPeople(); System.out.println("list 2:" + list1); list1.get(0).setName("zdh"); List list2 = collectionGetterSetterObject.getListPeople(); System.out.println("List 3:" + list2); } }

对象集合的正确封装 在上面的基础上修改Getter、Setter,并且自定义复制克隆Person对象方法

private List listPeople = new ArrayList(); // private List listPeople; public void setListPeople(List listPeople) { for (Person person : listPeople) { this.listPeople.add((Person) person.clone()); } } public List getListPeople() { List list = new ArrayList(); for (Person person : this.listPeople) { list.add((Person) person.clone()); } return list; }

clone.method

public Object clone() { Person aClone = new Person(this.name); return aClone; } 为自己的类型实现getter和setter class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String toString() { return this.name; } public Object clone() { Person aClone = new Person(this.name); return aClone; } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3