I'm adding this answer since Sumeet's is outdated as of 2019.
You can provide your own getter or setter logic by simply writing your own methods.
package com.example;
import lombok.Getter;
@Getter
public class Foo {
//Will not generate a getter for 'test'
private String test;
//Will generate a getter for 'num' because we haven't provided our own
private int num;
public String getTest(){
if(test == null){
throw new Exception("Don't mind me, I'm just a silly exception");
}
return test;
}
}
Answer from rath on Stack OverflowI'm adding this answer since Sumeet's is outdated as of 2019.
You can provide your own getter or setter logic by simply writing your own methods.
package com.example;
import lombok.Getter;
@Getter
public class Foo {
//Will not generate a getter for 'test'
private String test;
//Will generate a getter for 'num' because we haven't provided our own
private int num;
public String getTest(){
if(test == null){
throw new Exception("Don't mind me, I'm just a silly exception");
}
return test;
}
}
I assume you meant to use Integer instead of int, which does not allow null values and therefore solves your problem :)
In general, I would not recommend to change the logic of setFoo. Silently not setting foo on an arbitrary condition would expose its usage to bugs or at least misunderstandings.
My suggestion is to either use a custom method explicitly named setFooIfNotNull(Integer foo). A possible alternative solution would be to mark the field foo with the annotation @NonNull to throw a NullPointerException in a case of null values.
From the Lombok @Setter annotation documentation 'small print':
Any annotations named @NonNull (case insensitive) on the field are interpreted as: This field must not ever hold null. Therefore, these annotations result in an explicit null check in the generated setter.
Per the documentation for @Builder: Just define enough skeleton yourself. In particular, Lombok will generate a class UserBuilder, fields mirroring the User fields, and builder methods, and you can provide any or all of this yourself.
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String username;
private String password;
public static class UserBuilder {
public UserBuilder password(String password) {
this.password = ENCODER.encode(password);
return this;
}
}
}
I've accepted chrylis's answer but for completeness, here's are some ways to minimize customization and duplication.
Custom setter and builder with static helper
A static helper can be used to share most of the set password functionality across the custom User.UserBuilder::password method and the custom User::setPassword method:
@Data
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String password = null;
public void setPassword(String password) {
this.password = _encodePassword(password);
}
public static class UserBuilder {
public UserBuilder password(String password) {
this.password = _encodePassword(password)
return this;
}
}
private static String _encodePassword(String password) {
Assert.notNull(password);
return ENCODER.encode(password);
}
}
Custom setter and constructor
A custom constructor can use User::setPassword which is invoked by the Lombok generated User.UserBuilder::build():
@Data
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String password = null;
User(String password) {
setPassword(password);
}
public void setPassword(String password) {
Assert.notNull(password);
this.password = ENCODER.encode(password);
}
}
Custom setter and constructor with static helper
Or, a little more elegantly, with a custom constructor and a static helper method:
@Data
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String password = null;
User(String password) {
_encodePassword(password, this);
}
public void setPassword(String password) {
_encodePassword(password, this);
}
private static _encodePassword(String password, User user) {
Assert.notNull(password);
user.password = ENCODER.encode(password);
}
}
I dont know why you need this, but here is the approach to custom Getters and Setters. You can update all generated setters and getters by going to preferences > java > Code Style > code Templates and selecting code then edit Getter body and Setter body and put this:
Getter body: return get(${field});
Setter body: set(${field}, ${param});
Let me know if that works
I recommend that instead of doing what you describe, you should use Spring Data. Specifically the BeanPropertyRowMapper class in the org.springframework.jdbc.core package will do what you want.
Read more in the Spring API documentation.
You can update all generated variables with a prefix by going to preferences > java > Code Style and selecting Parameters then edit. You can add a prefix/suffix for all generated variable names.
there are two thing that you need to do to effect the setter in your example.
first, as others have mentioned, you will need to go to the Preferences dialog and go to Java/Code Style/Code Templates/Code/Setter body. in the Pattern box, you should make the value to look like this:
this.${field} = ${param};
second, still in the Preferences dialog, go up a level to Code Style. Here you will see a table 'Conventions for variable names.' Select the Parameters row and select edit. add the letter a to the prefix field.
Once all of that is saved, you should be able to automatically generate setters as you have defined above, using the Generate Getter and Setter" command.
You can create a live template:
http://www.jetbrains.com/idea/webhelp/creating-and-editing-live-templates.html
This should work like:
public void set$CAP_SELECTION$(String $SELECTION$) {
if(this.$SELECTION$!=null)
throw new IlegalArgumentException("$SELECTION$already set");
this.$SELECTION$=$SELECTION$;
}
You just write:
lastname, select the test and use the template
CAP_SELECTION is a variable in kind of capitalize($SELECTION)
IntelliJ IDEA has no way to customize getter/setter templates, vote for this request.
A workaround would be to create a Surround live template. This way you can type the variable, like lastname, then select it and invoke Surround template that will convert the selection into
public void setLastname(String lastname) {
if(this.lastname!=null)
throw new IlegalArgumentException("lastname already set");
this.lastname=lastname;
}
Refer to the documentation for details.
Based on the current version's documentation (https://projectlombok.org/features/GetterSetter), it doesn't seem to include a way to specify custom checks for the setter (or getter). I fear you will have to manually code each and every setter.
The same applies for the experimental @Accessor feature.
As @Laf said, Lombok doesn't currently support this feature. However, you still can get rid of some duplicated code by extracting setters logic to the following higher-order function:
private void doSetTacLacStartUe(
Integer oldValue,
Integer newValue,
Consumer<Integer> setter,
BiConsumer<EventDocument, Integer> eventDocumentUpdater
) {
if (Objects.equals(oldValue, newValue)) return;
setter.accept(newValue);
if (DocKind.ORIG == docKind)
eventDocumentUpdater.accept((EventDocument) prepareDirtyDocument(), newValue);
}
And using it this way:
public void setTacLacStartUe1(Integer tacLacStartUe1) {
doSetTacLacStartUe(getTacLacStartUe1(), tacLacStartUe1, it -> this.tacLacStartUe1 = it, EventDocument::setTacLacStartUe1);
}
I'm assuming you mean a setter method as in set an object?
private String yourString;
public void setYourString(String yourString) {
this.yourString = yourString;
}
This is basic code though so you probably mean something else?
Let me know.
A setter is a method which sets a value for one of your parameters. E.g. many people say it's not nice to have a public variable in a class:
public class SomeClass {
public int someInt = 0;
}
now you can access the variable someInt directly:
SomeClass foo = new SomeClass();
foo.someInt = 13;
You should rather do something like that:
public class SomeClass {
private int someInt = 0;
// Getter
public int getSomeInt() {
return someInt;
}
// Setter
public void setSomeInt(int someIntNew) {
someInt = someIntNew;
}
}
and access it through:
SomeClass foo = new SomeClass();
foo.setSomeInt(13);
All this is just convention... You could name your setter-method however you want! But getters and setters are a good (and readable) way to define access to your class varaibles as you like it (if you want to make it read-only you could just write the getter, if you don't wan't anybody to read the value you could only write the setter, you could make them protected, etc...)