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.
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
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();
}
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 think this question has been asked like a million times, but none of solutions suggested worked for me. Here is my sample implementation
public class FooImpl2 implements Foo {
private int a = 100 ;
private String b = "I am FooImpl2";
private boolean c;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public boolean isC() {
return c;
}
public void setC(boolean c) {
this.c = c;
}
}
#XmlRootElement
#XmlSeeAlso({FooImpl1.class, FooImpl2.class})
public interface Foo {}
public class FooImpl1 implements Foo {
private int x;
private String y ="I am FooImpl1";
private boolean z;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
public boolean isZ() {
return z;
}
public void setZ(boolean z) {
this.z = z;
}
}
#XmlRootElement
public class Response{
private Foo foo;
#XmlElement(type=Object.class)
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
public class SimpleResource {
#Path("foo/{val}") #Produces({"application/json"}) #GET
public FooAdapter getFoo(#QueryParam("val") int val) {
FooAdapter ret = new FooAdapter();
if(val % 2 == 0) {
ret.setFoo(new FooImpl2());
} else {
ret.setFoo(new FooImpl1());
}
return ret;
}
I always get following exception
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of
IllegalAnnotationExceptions
com.abc.objectsToReturn.Foo is an
interface,
can any one help me to figure out right solution
This isn't really an interface issue, you just need to change the way you bootstrap your JAXBContext.
If you change it to the following:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Response.class, FooImpl1.class, FooImpl2.class);
Response response = new Response();
FooImpl1 foo = new FooImpl1();
response.setFoo(foo);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(response, System.out);
}
}
Then you will get the following output (with any JAXB implementation: Metro, MOXy, etc):
<response>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="fooImpl1">
<x>0</x>
<y>I am FooImpl1</y>
<z>false</z>
</foo>
</response>
MOXy JAXB allows your entire model to be interfaces, checkout:
http://bdoughan.blogspot.com/2010/07/moxy-jaxb-map-interfaces-to-xml.html
I also have a blog post that may be relevant to what you are trying to build:
http://bdoughan.blogspot.com/2010/08/using-xmlanyelement-to-build-generic.html
When you use interfaces just to hide your implementation classes from exposure, and when there's 1-to-1 (or close to 1-on-1) relationship between a class and an interface, XmlJavaTypeAdapter can be used like below.
#XmlJavaTypeAdapter(FooImpl.Adapter.class)
interface IFoo {
...
}
class FooImpl implements IFoo {
#XmlAttribute
private String name;
#XmlElement
private int x;
...
static class Adapter extends XmlAdapter<FooImpl,IFoo> {
IFoo unmarshal(FooImpl v) { return v; }
FooImpl marshal(IFoo v) { return (FooImpl)v; }
}
}
class Somewhere {
public IFoo lhs;
public IFoo rhs;
}
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