Is there a way to tell Lombok to append a piece of code to each generated setter?
Example:
#Setter
public class Foo {
private int a;
private int b;
private void update() { /* ... */ }
}
would generate
public void setA(int a) {
this.a = a;
update();
}
public void setB(int b) {
this.b = b;
update();
}
Related
I am using MapStruct 1.5.2.Final
Map struct is unable to map the target values using the parameterised constructor. Following is the parameterised constructor for the class.
I know that if I would have exposed the setters, this would have worked.
I don't want to expose the setters for my class as I want my class to be immutable.
#JsonCreator
public PassengerInfo(
#JsonProperty("a") final String a,
#JsonProperty("b") final String b) {
this.a = a;
this.b = b;
}
I am getting the following error
error: Property "a" has no write accessor in class.
error: Property "b" has no write accessor in class.
Also, this is the only constructor in my class.
Following is my class
public class Clazz {
private final String a;
private final String b;
#JsonCreator
public Clazz(
#JsonProperty("a") final String a,
#JsonProperty("b") final String b) {
this.a = a;
this.b = b;
}
public String getA() {
return a;
}
public String getB() {
return b;
}
}
Your code seems fine. There must be something else in your project.
#Getter
#Setter
public class PassengerEntity {
private String a;
private String b;
}
public class PassengerInfo {
private final String a;
private final String b;
#JsonCreator
public PassengerInfo(
#JsonProperty("a") final String a,
#JsonProperty("b") final String b) {
this.a = a;
this.b = b;
}
public String getA() {
return a;
}
public String getB() {
return b;
}
}
#Mapper
public interface PassengerMapper {
PassengerInfo mapPassenger(PassengerEntity entity);
}
class PassengerMapperTest {
private PassengerMapper passengerMapper;
#BeforeEach
void setUp() {
passengerMapper = Mappers.getMapper(PassengerMapper.class);
}
#Test
void testMapper() {
PassengerEntity entity = new PassengerEntity();
entity.setA("valueA");
entity.setB("valueB");
PassengerInfo info = passengerMapper.mapPassenger(entity);
Assertions.assertEquals("valueA", info.getA());
Assertions.assertEquals("valueB", info.getB());
}
}
=> test is OK
Here's what I'd like to do. Let's say I have this code:
public class Foo {
private Bar bar = new Bar();
public void doWork() {
bar.setA(5);
bar.setB(10);
}
}
public class Bar {
private int a;
private int b;
public void setA(int a) { this.a = a; }
public void setB(int b) { this.b = b; }
...
}
I want to extract members a and b from Bar into a separate Container class and end up with this code. Notice that Foo doesn't call setA on bar anymore, instead it requests container and calls a setter on it instead:
public class Foo {
private Bar bar = new Bar();
public void doWork() {
bar.getContainer.setA(5);
bar.getContainer.setB(10);
}
}
public class Bar {
private Container container;
public Container getContainer() { return container; }
...
}
public class Container {
private int a;
private int b;
public void setA(int a) { this.a = a; }
public void setB(int b) { this.b = b; }
...
}
Is there a way to do this in IntelliJ?
I could try using Refactor -> Extract -> Delegate, but in that case IntelliJ leaves setA and setB methods in Bar and doesn't change code in Foo:
public class Bar {
private Container container;
public void setA(int a) { container.setA(a); }
public void setB(int b) { container.setB(b); }
...
}
which is not quite what I want.
Select the piece of code inside class bar...
private int a;
private int b;
public void setA(int a) { this.a = a; }
public void setB(int b) { this.b = b; }
On the main menu, or from the context menu of the selection, choose Refactor | Extract | Method Object . You will also have option to choose to create inner class, or anonymous class. Hope this helps.
Here's my question, how can I change an object outside of it's class, so that it maintains the changes made in the outside class?
Here's an example of the code:
Main class:
public class Main {
public static void main(String[] args)
{
Variable var = new Variable(1,2,3);
Change.changeVar(var);
System.out.println("" + var.geta() + "" + var.getb() + "" + var.getc());
}
}
Variable class:
public class Variable {
private int a;
private int b;
private int c;
public Variable(int a, int b, int c)
{
this.a = a;
this.b = b;
this.c = c;
}
public int geta()
{
return this.a;
}
public int getb()
{
return this.b;
}
public int getc()
{
return this.c;
}
}
Change class:
public class Change {
public static void changeVar(Variable var)
{
Variable var2 = new Variable(4,5,6);
var = var2;
}
}
In your example, no. When changeVar() exits, the parameter var is discarded, and the var in your main() method retains its original value. Read up on pass by reference.
public class Variable {
private int a;
private int b;
private int c;
public Variable(int a, int b, int c)
{
this.a = a;
this.b = b;
this.c = c;
}
public int geta()
{
return this.a;
}
public int getb()
{
return this.b;
}
public int getc()
{
return this.c;
}
// depending on your use case, setters might be more appropriate
// it depends on how you want to control the changing of the vars
public void update(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
}
public class Change {
public static void changeVar(Variable var)
{
var.update(4,5,6);
}
}
You cannot do it in a way that you described, because in Java variables are passed by values. However you can achieve the desired effect in a different way:
public class Variable {
private int a;
private int b;
private int c;
public Variable(int a, int b, int c)
{
this.a = a;
this.b = b;
this.c = c;
}
public int geta()
{
return this.a;
}
public int getb()
{
return this.b;
}
public int getc()
{
return this.c;
}
public void seta(int a) { this.a = a; }
public void setb(int b) { this.a = b; }
public void setc(int c) { this.a = c; }
}
public class Change {
public static void changeVar(Variable var)
{
var.seta(4);
var.setb(5);
var.setc(6);
}
}
You need to provide setter methods and call them on the original object:
public void seta(int newa) { this.a = newa; }
Then you would say
public static void changeVar(Variable var)
{
var.seta(4);
//etc
}
You are merely repointing the local variable reference var to point to your new instance var2. It has no effect on the value of the original instance passed into the method.
Doing it that way? You can't.
You're passing a reference to the instance. However, inside the function, you use a new reference. Assigning to the new reference does not affect others.
public static void changeVar(Variable var)
{
Variable var2 = new Variable(4,5,6);
var = var2;
}
first, u can write some setter methods in Variable class, then you can call these setter methods in the above code, like var.setA(4) ... and so on.enter code here
I got an implementation of Parcelable working for a single class that involves no inheritance. I have problems figuring out the best way to implement the interface when it come to inheritance. Let's say I got this :
public abstract class A {
private int a;
protected A(int a) { this.a = a; }
}
public class B extends A {
private int b;
public B(int a, int b) { super(a); this.b = b; }
}
Question is, which is the recommended way to implement the Parcelable interface for B (in A? in both of them? How?)
Here is my best solution, I would be happy to hear from somebody that had a thought about it.
public abstract class A implements Parcelable {
private int a;
protected A(int a) {
this.a = a;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(a);
}
protected A(Parcel in) {
a = in.readInt();
}
}
public class B extends A {
private int b;
public B(int a, int b) {
super(a);
this.b = b;
}
public static final Parcelable.Creator<B> CREATOR = new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(b);
}
private B(Parcel in) {
super(in);
b = in.readInt();
}
}
This is my variant. I think it's nice because it shows the symmetry between the virtual read- and write- methods very clearly.
Side note: I think Google did a really poor job at designing the Parcelable interface.
public abstract class A implements Parcelable {
private int a;
protected A(int a) {
this.a = a;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(a);
}
public void readFromParcel(Parcel in) {
a = in.readInt();
}
}
public class B extends A {
private int b;
public B(int a, int b) {
super(a);
this.b = b;
}
public static final Parcelable.Creator<B> CREATOR = new Parcelable.Creator<B>() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(b);
}
public void readFromParcel(Parcel in) {
super(in);
b = in.readInt();
}
}
Here is the implementation for class A in a real world setting since class B will likely have more than one object with different types other than int
It uses reflection to get the types. Then uses a sorting function to sort the fields so that reading and writing happen in the same order.
https://github.com/awadalaa/Android-Global-Parcelable
For bean->xml convertion in webservices we use Aegis from CXF (it is jaxb-compatible, as I understand).
This is my type:
class C{
private int a;
private int b;
private T t;
...
}
class T{
private int t1;
private int t2;
}
I need t.t1 field to be on the same level in XML as a and b in C (bean restored from xml should be like this:
class C{
private int a;
private int b;
private int t1
}
(client code is interested only in field t1 from structure T).
Thanks.
You could add getT1() and setT1(int) to C and make getT() #XmlTransient
class C {
// snip
/**
* JAXB only
*/
#SuppressWarnings("unused")
#XmlElement
private void setT1(int t1) {
if(t != null) {
t.setT1(t1);
} else {
// TODO
}
}
/**
* JAXB only
*/
#SuppressWarnings("unused")
private int getT1() {
if(t != null) {
return t.getT1(t1);
} else {
// TODO
}
}
}