Java get all setters

Java get all setters

Вопрос, почему мы не задаем в конструкторе класса значение через сеттер (в котором выполнена проверка на валидность), а задаем что-то типа this.value = value (вместо setValue(value)) ?? Ниже написал код в виде примера. Если бы в конструкторе было this.value = value, то при инициализации объекта значением например -3 в конструкторе всё было бы ОК. А сеттер в конструкторе не даст сделать такой глупости.

 public class Main < public static void main(String[] args) < //это значение не вызовет ошибку, пока оно положительное: MyClass myClass = new MyClass(3); //MyClass myClass = new MyClass(-3) //тут будет ошибка! myClass.setValue(4); //это значение не вызовет ошибку //myClass.setValue(-4); //а это вызовет ошибку! System.out.println(myClass.getValue()); >> class MyClass < private int value; public MyClass(int value) < setValue(value); >public int getValue() < return value; >public void setValue(int value) < if (value < 0) < throw new IllegalArgumentException ("Значение value должно быть положительным числом!"); >this.value = value; > > 

Для быстрого создания getter и setter в IntelliJ IDEA выделяете переменную класса и нажимаете alt + insert, во всплывшем окошке можно выбрать что хотите создать.

Интересно, почему в гетере пишут просто return name а можно написать так public String getName() < return this.name; >потому что так просто короче? Или функционал меняется?

Что-то я не совсем понял, даже если я объявил переменную класса private но создал сеттер, то мой объект извне можно все равно изменять, разница лишь в проверке значений. А если я не хочу чтобы мой объект изменяли, то я просто не пишу сеттер? Но смогу ли я сам менять значения объекта?

в конструкторе ведь то же можно указать ограничения при создании объекта?,и еще вопрос в Idea можно изменить название переменной сделав пару кликов,и оно меняется везде в коде вот эта замена это аналог замены через сеттер без потери потерь или там более простая логика и он тупо меняет названия?

Источник

Finding Getters and Setters with Java Reflection

Java Reflection provides a set of useful APIs that help you find methods in Java classes. You can find all the methods in a class or a method with a specific name and signature. Surprisingly, there are no APIs to determine if a Java method is a getter or a setter.

In this post, I’ll develop a useful method that returns a list of getters and setters for any Java class. I’ll also create separate methods that inspect Java Reflection Method objects and determine if the method they represent is a getter or a setter.

A Class with Getters and Setters

We’ll need a class to work with, so here’s a Person class with getters and setters.

public class Person < private String name; private int age; private boolean deceased; public Person() < >public Person(String name, int age) < this.name = name; this.age = age; deceased = false; >public String getName() < return name; >public void setName(String name) < this.name = name; >public int getAge() < return age; >public void setAge(int age) < this.age = age; >public boolean isDeceased() < return deceased; >public void setDeceased(boolean deceased) < this.deceased = deceased; >public boolean isTeenager() < return (age >12 && age < 20) ? true : false; >@Override public String toString()

The Person class includes getters and setters that follow typical naming protocols. This includes the “ set ” and “ get ” methods for field data, as well as “ is ” methods with booleans. The toString() method in line 29 (which is not a getter or setter) is overridden to return a string with a Person ’s name and age.

Читайте также:  Java app android studio

Getter Methods

Before we move on, let’s review what makes a Java method a getter.

First of all, getter methods must be public. A getter method has no arguments and its return type must be something other than void.

Getters also have naming conventions. The name of a getter method begins with “ get ” followed by an uppercase letter. In the Person class, examples are getName() in line 11 and getAge() in line 15.

The name of a getter method can also begin with “ is ” followed by an uppercase letter. These getter methods do not have arguments and must return booleans. Examples are isDeceased() in line 19 and isTeenAger() in line 25 from the Person class.

Setter Methods

What makes a method a setter?

Setter methods must be public and have only one argument. Their return type must be void. Setter methods also have names that begin with “ set “, followed by an uppercase letter.

Examples in the Person class are setName() in line 12, setAge() in line 16, and setDeceased() in line 22.

The findGettersSetters() Method

Now we’re ready to develop several useful Java methods that find getter and setter methods in Java classes.

The first one is called findGettersSetters() .

static ArrayList findGettersSetters(Class c) < ArrayListlist = new ArrayList(); Method[] methods = c.getDeclaredMethods(); for (Method method : methods) if (isGetter(method) || isSetter(method)) list.add(method); return list; >

This method has a Class object argument and returns an ArrayList of Method objects representing the getters and setters in that class. The call to c.getDeclaredMethods() generates an array of class Method objects. We loop through this array and add a method to the ArrayList if it’s a getter or a setter.

The isGetter() and isSetter() methods inside the for loop determine if their Method object argument is a getter or setter, respectively. We’ll show you the code for these methods shortly.

Let’s try out findGettersSetters() with the Person class.

public static void main(String[] args)

public java.lang.String Person.getName() public void Person.setName(java.lang.String) public int Person.getAge() public void Person.setAge(int) public boolean Person.isDeceased() public void Person.setDeceased(boolean) public boolean Person.isTeenager()

The isGetter() Method

Our findGettersSetters() method uses isGetter() to find getters. This method has a Method object argument and returns a boolean (true if the method is a getter).

public static boolean isGetter(Method method) < if (Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 0) < if (method.getName().matches("^get[A-Z].*") && !method.getReturnType().equals(void.class)) return true; if (method.getName().matches("^is[A-Z].*") && method.getReturnType().equals(boolean.class)) return true; >return false; >

The first if statement makes sure the method is public and the method has no arguments.

The second if statement uses a regular expression to verify the method’s name begins with “ get ” followed by an uppercase letter. It also makes sure that the method’s return type is something other than void.

The third if statement verifies the method’s name begins with “ is ” followed by an uppercase letter and that the method’s return type is boolean.

The isSetter() Method

Our findGettersSetters() method also uses isSetter() to find setters. The implementation of this method is done with four steps in a single return statement.

public static boolean isSetter(Method method)

Step one makes sure the method is public. Step two verifies the method’s return type is void. Step three insures the method has one argument. The last step verifies that the method’s name begins with “ set ” followed by an uppercase letter.

In this post, I developed a findGettersSetters() method that returns a list of getter and setter Method objects for any Java class. I also created isGetter() and isSetter() boolean methods that determine if a specific class method is a getter or a setter.

Читайте также:  How to set java version

These three methods are useful when you need to find getters and setters in a class or need to know if a specific method is a getter or a setter.

If you’d like to learn more about Java Reflection and other techniques like these, check out my JavaReflection LiveLesson.

Java Reflection Live Lesson

Источник

Java get all setters

Как вы заметили, 2-й элемент массива scores изменяется вне сеттера (в строке 5). Поскольку геттер возвращает ссылку на scores, внешний код, имея эту ссылку, может вносить изменения в массив.

Решение этой проблемы заключается в том, что геттеру необходимо возвращать копию объекта, а не ссылку на оригинал. Модифицируем вышеупомянутый геттер следующим образом:

Переменные примитивных типов вы можете свободно передавать/возвращать прямо в сеттере/геттере, потому что Java автоматически копирует их значения. Таким образом, ошибок № 2 и № 3 можно избежать.

 private float amount; public void setAmount(float amount) < this.amount = amount; >public float getAmount()

String — это immutable-тип. Это означает, что после создания объекта этого типа, его значение нельзя изменить. Любые изменения будут приводить к созданию нового объекта String. Таким образом, как и для примитивных типов, вы можете безопасно реализовать геттер и сеттер для переменной String:

 private String address; public void setAddress(String address) < this.address = address; >public String getAddress()

Т.к. объекты класса java.util.Date являются изменяемыми, то внешние классы не должны иметь доступ к их оригиналам. Данный класс реализует метод clone() из класса Object, который возвращает копию объекта, но использовать его для этих целей не стоит.

По этому поводу Джошуа Блох пишет следующее: «Поскольку Date не является окончательным классом, нет га­рантии, что метод clone() возвратит объект, класс которого именно java.util.Date: он может вернуть экземпляр ненадежного подкласса, созданного специально для нанесения ущерба. Такой подкласс может, например, записы­вать ссылку на каждый экземпляр в момент создания последнего в закрытый статический список, а затем предоставить злоумышленнику доступ к этому списку. В результате злоумышленник получит полный контроль над всеми эк­земплярами копий. Чтобы предотвратить атаки такого рода, не используйте метод clone() для создания копии параметра, тип которого позволяет нена­дежным сторонам создавать подклассы».

Источник

Tech Tutorials

Tutorials and posts about Java, Spring, Hadoop and many more. Java code examples and interview questions. Spring code examples.

Monday, June 12, 2023

Invoking Getters And Setters Using Reflection in Java

In the post reflection in java – method it is already explained how you can invoke a method of the class at runtime. In this post we’ll use that knowledge to invoke getters and setters of the class using Java reflection API. In Java you can do it using two ways.

In this post we’ll see example of both of these ways to invoke getters and setters of the class.

Using PropertyDescriptor class

A PropertyDescriptor describes one property that a Java Bean exports via a pair of accessor methods. Then using the getReadMethod() and getWriteMethod() you can call the setter and getter for the property.

Invoking getters and setters using PropertyDescriptor example

Here in the example we have a class TestClass which has getter and setter for three fields which are of type int, String and boolean. Then in the GetterAndSetter class there are methods to invoke the getters and setters of the given class.

package org.prgm; public class TestClass < private int value; private String name; private boolean flag; public int getValue() < return value; >public void setValue(int value) < this.value = value; >public String getName() < return name; >public void setName(String name) < this.name = name; >public boolean isFlag() < return flag; >public void setFlag(boolean flag) < this.flag = flag; >>
import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; public class GetterAndSetter < public static void main(String[] args) < GetterAndSetter gs = new GetterAndSetter(); TestClass tc = new TestClass(); gs.callSetter(tc, "name", "John"); gs.callSetter(tc, "value", 12); gs.callSetter(tc, "flag", true); // Getting fields of the class Field[] fields = tc.getClass().getDeclaredFields(); for(Field f : fields)< String fieldName = f.getName(); System.out.println("Field Name -- " + fieldName); >gs.callGetter(tc, "name"); gs.callGetter(tc, "value"); gs.callGetter(tc, "flag"); > private void callSetter(Object obj, String fieldName, Object value) < PropertyDescriptor pd; try < pd = new PropertyDescriptor(fieldName, obj.getClass()); pd.getWriteMethod().invoke(obj, value); >catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) < // TODO Auto-generated catch block e.printStackTrace(); >> private void callGetter(Object obj, String fieldName) < PropertyDescriptor pd; try < pd = new PropertyDescriptor(fieldName, obj.getClass()); System.out.println("" + pd.getReadMethod().invoke(obj)); >catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) < // TODO Auto-generated catch block e.printStackTrace(); >> >
Field Name -- value Field Name -- name Field Name -- flag John 12 true

Scanning methods of the class and look for set and get methods

Another way to invoke the getters and setters using Java reflection is to scan all the methods of the class through reflection and then find out which are the getters and setters method.

Читайте также:  Язык питон примеры программ

It is particularly useful to use this way to call get methods if you have lots of fields in a class. Calling set method that way won’t be of much help as you will have to still invoke individual method with the value that has to be set.

Logic to identify get method

get method starts with get or is (in case of boolean), it should not have any parameters and it should return a value.

Logic to identify set method

set method starts with set and it should have a parameter and it shouldn’t return any value which means it should return void.

In the example same Java bean class as above TestClass is used.

In the GetterAndSetter class there are methods to identify the getters and setters of the given class. If it is a get method that is invoked to get the value. For set method invocation is done to set the property values.

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class GetterAndSetter < public static void main(String[] args) < TestClass tc = new TestClass(); // get all the methods of the class Method[] methods = tc.getClass().getDeclaredMethods(); // Initially calling all the set methods to set values for(Method method : methods)< if(isSetter(method))< System.out.println("Setter -- " + method.getName()); try < if(method.getName().contains("Name")) < method.invoke(tc, "John"); >if(method.getName().contains("Value")) < method.invoke(tc, 12); >if(method.getName().contains("Flag")) < method.invoke(tc, true); >> catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) < // TODO Auto-generated catch block e.printStackTrace(); >> > // calling getters for(Method method : methods) < if(isGetter(method))< try < Object obj = method.invoke(tc); System.out.println("Invoking "+ method.getName() + " Returned Value - " + obj); >catch (IllegalAccessException e) < // TODO Auto-generated catch block e.printStackTrace(); >catch (IllegalArgumentException e) < // TODO Auto-generated catch block e.printStackTrace(); >catch (InvocationTargetException e) < // TODO Auto-generated catch block e.printStackTrace(); >> > > private static boolean isGetter(Method method) < // identify get methods if((method.getName().startsWith("get") || method.getName().startsWith("is")) && method.getParameterCount() == 0 && !method.getReturnType().equals(void.class))< return true; >return false; > private static boolean isSetter(Method method) < // identify set methods if(method.getName().startsWith("set") && method.getParameterCount() == 1 && method.getReturnType().equals(void.class))< return true; >return false; > >
Setter -- setName Setter -- setValue Setter -- setFlag Invoking getName Returned Value - John Invoking getValue Returned Value - 12 Invoking isFlag Returned Value - true

That’s all for this topic Invoking Getters And Setters Using Reflection in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!

Источник

Оцените статью