I have a class like this:
import java.util.List;
import java.util.String;
import javax.xml.bind.annotation.XmlType;
#XmlType
public class Foo {
private List<Foo> compound;
private String bar;
// private method used internally to know
// if this is a compound instance
private boolean isCompound() {
return compound != null && compound.size() != 0;
}
// public setter for compound instance var
public void setCompound(List<Foo> compound) {
this.compound = compound;
}
// public getter for compound instance var
public List<Foo> getCompound() {
return compound;
}
public void setBar(String bar) {
this.bar = bar;
}
public String getBar() {
return bar;
}
}
In normal use, this class behaves as you would expect. The methods getCompound and setCompound get and set the compound list. However, I'm using this class as an object that's passed in a web service built using JAX-WS. When the JAX-WS compiler sees this class, it ignores the setCompound and getCompound accessors, and the only property that appears in the XSD is bar.
After banging my head against the wall for most of the day, I decided to try changing the name of the private method isCompound to isACompound and suddenly everything worked as you'd expect. JAX-WS created the correct schema for the compound property.
What seems to be happening is that JAX-WS is seeing the isCompound method (even though it's private) and treating it as a getter with no corresponding setter and therefore ignoring the real public accessors for compound.
Is there anything in the Java Bean specification that says you can't have a private is<Something> method where <something> is also the name of a non-boolean property, which also has its own accessors? Surely anything using reflection on the class should simply ignore private methods?
What happens if you change:
return compound != null && compound.size() != 0;
//To:
private boolean isCompound() {
boolean check = false;
if(compound !=null && compound.size()!=0){
check = true;
}else{
check =false;
}
return check;
}
//or
#XmlAccessorType(XmlAccessType.NONE) on the class and #XmlElement and #XmlAttribute on the get/set methods.
Related
I have the following classes: Command, ParameterData, and TestCommand. Command is an abstract class that represents a simple object. This class requires a list of ParameterData objects. ParameterData, in turn, also requires an instance of the Command class in its constructor. I wanted to create a class inheriting from Command, i.e. TestCommand. Here's the problem: when invoking the constructor, I get a compile error: "Cannot reference 'this' before supertype constructor has been called". I don't know how to fix this problem. I will be grateful for your help.
Command class:
public abstract class Command {
private final String SETTINGS_PATH;
private final List<ParameterData> PARAMETERS;
public Command(String settingsPath, List<ParameterData> parameters) {
this.SETTINGS_PATH = settingsPath;
this.PARAMETERS = parameters;
}
public String getSettingsPath() {
return SETTINGS_PATH;
}
public abstract void run();
}
ParameterData class:
public class ParameterData {
private final String SETTINGS_KEY;
private final Command COMMAND;
private final OptionType OPTION_TYPE;
private final boolean REQUIRED;
public ParameterData(String settingsKey, Command command, OptionType optionType, boolean required) {
this.SETTINGS_KEY = settingsKey;
this.COMMAND = command;
this.OPTION_TYPE = optionType;
this.REQUIRED = required;
}
public String getSettingsKey() {
return SETTINGS_KEY;
}
public String getSettingsPath() {
return COMMAND.getSettingsPath() + ".Parameters." + SETTINGS_KEY;
}
public OptionType getOptionType() {
return OPTION_TYPE;
}
public boolean isRequired() {
return REQUIRED;
}
}
TestCommand class (error occurs with "this"):
public class TestCommand extends Command {
public TestCommand() {
super("Settings.TestCommand",
List.of(new ParameterData("SettingsKey", this, OptionType.STRING, true)));
}
#Override
public void run() {
//do something
}
}
I don't know how to fix this problem.
It cannot be fixed. You can't hand an instance of this around when your this reference isn't initialized yet. Think about it, it's a chicken and egg problem: That this reference has all sorts of crazy stuff going on. It'll have final fields that aren't initialized yet, i.e. final fields whose value will be changing if you query it.
Within the chain of constructors, thems the breaks. But you're not allowed to aggravate this problem by sending this to other places when this isn't "ready yet". Constructors are part of the 'birth' of an object and this refers to the baby. You can't hand your baby to others to coo at when it's not (fully) born yet.
If you want 2 objects that refer to each other, both with final fields? Not possible.
Make one field non-final. Use a builder system and make the 'setters' for this non-final field package private or fully private and whilst the field isn't final, your object will still be immutable for all intents and purposes - it cannot be observed to change once it escapes its package.
I have a class that I want to use Lombok.Builder and I need pre-process of some parameters. Something like this:
#Builder
public class Foo {
public String val1;
public int val2;
public List<String> listValues;
public void init(){
// do some checks with the values.
}
}
normally I would just call init() on a NoArg constructor, but with the generated builder I'm unable to do so. Is there a way for this init be called by the generated builder? For example build() would generate a code like:
public Foo build() {
Foo foo = Foo(params....)
foo.init();
return foo;
}
I'm aware that I can manually code the all args constructor, that the Builder will call through it and I can call init inside there.
But that is a sub-optimal solution as my class will likely have new fields added every once in a while which would mean changing the constructor too.
In Foo you could manually add a constructor, have that do the initialization, and put #Builder on the constructor. I know that you already know this, but I think it is the right solution, and you won't forget to add the parameter since you do want to use the code in the builder anyway.
Disclosure: I am a lombok developer.
After much trial and end error I found a suitable solution: extend the generate builder and call init() myself.
Example:
#Builder(toBuilder = true, builderClassName = "FooInternalBuilder", builderMethodName = "internalBuilder")
public class Foo {
public String val1;
public int val2;
#Singular public List<String> listValues;
void init() {
// perform values initialisation
}
public static Builder builder() {
return new Builder();
}
public static class Builder extends FooInternalBuilder {
Builder() {
super();
}
#Override public Foo build() {
Foo foo = super.build();
foo.init();
return foo;
}
}
}
I just stumbled upon the same issue. But additionally, I wanted to add an method buildOptional() to the builder to not repeat Optional.of(Foo) each time I need it. This did not work with the approach posted before because the chained methods return FooInternalBuilder objects; and putting buildOptional() into FooInternalBuilder would miss the init() method execution in Builder...
Also, I personally did not like the presence of 2 builder classes.
Here is what I did instead:
#Builder(buildMethodName = "buildInternal")
#ToString
public class Foo {
public String val1;
public int val2;
#Singular public List<String> listValues;
public void init(){
// do some checks with the values.
}
/** Add some functionality to the generated builder class */
public static class FooBuilder {
public Optional<Foo> buildOptional() {
return Optional.of(this.build());
}
public Foo build() {
Foo foo = this.buildInternal();
foo.init();
return foo;
}
}
}
You can do a quick test with this main method:
public static void main(String[] args) {
Foo foo = Foo.builder().val1("String").val2(14)
.listValue("1").listValue("2").build();
System.out.println(foo);
Optional<Foo> fooOpt = Foo.builder().val1("String").val2(14)
.listValue("1").listValue("2").buildOptional();
System.out.println(fooOpt);
}
Doing so let's you add what I want:
Add an init() method which is executed after each object construction automatically
Adding new fields do not require additional work (as it would be for an individually written constructor)
Possibility to add additional functionality (incl. the init() execution)
Retain the complete
standard functionality the #Builder annotation brings
Don't expose an additional builder class
Even if you solved your problem before I like to share this as the solution. It is a bit shorter and adds a (for me) nice feature.
This works for me, not a complete solution, but quick and easy.
#Builder
#AllArgsConstructor
public class Foo {
#Builder.Default
int bar = 42;
Foo init() {
// perform values initialisation
bar = 451; // replaces 314
return foo;
}
static Foo test() {
return new FooBuilder() // defaults to 42
.bar(314) // replaces 42 with 314
.build()
.init(); // replaces 314 with 451
}
}
I was wondering, what if I have the following case:
public class MyObject<T> {
private T myTObject;
public void setMyTObject(T m) {
myTObject = m;
}
public T getMyTObject() {
return myTObject;
}
}
And now I want that class to react something like these:
MyObject<ObjectA> objA = new MyObject<ObjectA>();
ObjectA objAInstance = objA.getObjectA();
or
objA.setObjectA(otherObjectAInstance);
Is there a way to dynamically create methods based on T class name?
Or should I better extend ObjectA to MyObject and create those methods using super.get/seMyObject()?
For clarification:
The idea is to have a getter and setter method generated dynamically
so, if I create an instance of:
MyObject<A> objA = new MyObject<A>();
I would be able to call method:
objA.getA();
getA() will call internally getMyTObject() or just return myTObject
so MyObject may react based on T class and generate the corresponding method.
I have updated member attribute to differentiate from MyObject class, it may lead to confusion. also fixed Method return and parameter Type.
Update Answer is completely changed.
Sounds like you want to use something through reflection. The problem with truly dynamically generating the method names is that, as others have commented, it would have to be done in bytecode which means that other classes trying to use your dynamic classes don't have Java code to refer to. It can be done, but it would be a mess.
Instead, here's a possible solution using generics. Please note that this is something of a quick and dirty hack; I leave it to you to refine it. You define an interface with the getters and setters you want, with whatever you want them named:
package com.example.dcsohl;
public interface IntegerWrapper {
public Integer getInteger();
public void setInteger(Integer i);
}
And then, to use them, you use this class to do the heavy lifting. Note that the error checking isn't very good; for example, it doesn't check that "getFoo" at all corresponds to the name of the class being passed in; nor does it validate that the "foo" in "getFoo" matches the "setFoo" method. This is something you can improve on.
package com.example.dcsohl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyWrapper<T> implements InvocationHandler {
Class<T> clazz = null;
T myvalue = null;
public static <W,T> W getInstance(Class<W> clazz, Class<T> clazz2) {
ProxyWrapper<T> wrapper = new ProxyWrapper<T>();
wrapper.setClass(clazz2);
#SuppressWarnings("unchecked")
W proxy = (W)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, wrapper);
return proxy;
}
private void setClass(Class<T> clazz) {
this.clazz = clazz;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// getter has no arguments
if (method.getName().startsWith("get") && (args == null || args.length == 0)) {
return myvalue;
} else if (method.getName().startsWith("set") && args.length == 1) {
Object o = args[0];
if (o.getClass().isAssignableFrom(clazz)) {
#SuppressWarnings("unchecked")
T val = (T)o;
myvalue = val;
return null;
}
} else {
throw new Exception();
}
return null;
}
}
Finally, to use it, here's a quick sample:
package com.example.dcsohl;
public class Main {
public static void main(String[] args) {
Integer foo = 5;
IntegerWrapper wrapper = ProxyWrapper.getInstance(IntegerWrapper.class, Integer.class);
wrapper.setInteger(foo);
Integer bar = wrapper.getInteger();
System.out.println(bar);
}
}
It seems like a lot of work just to avoid writing simple wrapper classes, and you'd be right, but reflection has its uses, and this is something of a sampler.
This may seem a basic question, but I'd like to get this right.
I have a Class 'AWorld'. Within that class, I have a method that draws a border, depending on the map size set by the user.
If the variable 'mapSize' is private, but I want to access it's value from within the same class, is it more appropriate to reference it directly, or use a getter method.
The code below should explain what I'm wanting to know.
package javaFX;
public class AWorld {
//initialized later
AWorld newWorld;
private int mapSize = 20;
public int getMapSize()
{
return mapSize;
}
public void someMethod()
{
int var = newWorld.mapSize; //Do I reference 'mapSize' using this...
}
// Or...
public void someOtherMethod()
{
int var = newWorld.getMapSize(); //Or this?
}
public static void main(String[] args) {}
}
Either of those is ok since you're getting a primitive field. If the get method does another operation before returning the data e.g. performing a math operation on the value, then it would be better to use it rather than calling the field directly. This is specially meant when using proxy/decorator pattern on your classes.
Here's an example of the second statement from above:
//base class to be decorated
abstract class Foo {
private int x;
protected Foo foo;
public int getX() { return this.x; }
public void setX(int x) { this.x = x; }
public Foo getFoo() { return this.foo; }
//method to prove the difference between using getter and simple value
public final void printInternalX() {
if (foo != null) {
System.out.println(foo.x);
System.out.println(foo.getX());
}
}
}
//specific class implementation to be decorated
class Bar extends Foo {
#Override
public int getX() {
return super.getX() * 10;
}
}
//decorator
class Baz extends Foo {
public Baz(Foo foo) {
this.foo = foo;
}
}
public class Main {
public static void main(String[] args) {
Foo foo1 = new Bar();
foo1.setX(10);
Foo foo2 = new Bar(foo1);
//here you see the difference
foo2.printInternalX();
}
}
Output:
10
100
You better dereference it directly.
The point of the private modifier is not to expose internal implementation to other classes. These other classes will use the getter method to get the value of the private property.
In your own class, there is no point on using the getter. Worse, someone may have overridden that method in a class that extends your class, and the getter may perform something that you do not expect
IMHO, if you are referencing a field of the current instance the general rule is to access the field directly with mapSize or this.mapSize.
If you are referencing a value from a different instance (be it of the same class or a different class, I would use the getter method). I believe this would lead to simpler refactoring. It also maintains the contract that any other instance gets the field value via the getter which allows for additional functionality in the getter.
This question already has answers here:
How to refer to the outer class in another instance of a non-static inner class?
(3 answers)
Closed 8 years ago.
I am currently wondering if there is a good way of implementing an equals method for a non-static inner class in Java. I basically a class Foo with an inner-class Bar like this:
public class Foo {
private final String foo; // constructor omitted
public /* non-static */ class Bar {
private final String bar; // constructor omitted
#Override
public boolean equals(Object other) {
return other != null && other.getClass() == getClass()
&& ((Bar) other).bar.equals(this.bar)
&& Foo.this.equals(Foo.((Bar) other)); // Will, of course, not compile.
}
}
#Override
public boolean equals(Object other) {
return other != null && other.getClass() == getClass()
&& ((Foo) other).foo.equals(foo);
}
}
My classes are a lot more complex in reality and I want to reuse the Foo#equals method from within Bar#equals in order to save me a lot of code. I am now considering to make the "inner-class-relationship" explicit in order to being able to refer to the "outer" class. However, then I have to add accessor methods manually and I want to avoid this. I cannot get rid of the feeling that there should be a Java approach of doing this.
Yes, this is possible. This is often done when you need to pass around "Key" objects that represent a unique identifier for some set of data but do not either have the data or want to transport it.
class SomeData {
private String data;
public static class Key {
private final int firstId;
private final int secondId;
public Key(int firstId, int secondId) {
this.firstId = firstId;
this.secondId = secondId;
}
public boolean equals(Object x) {
if(!(x instanceof Key))
return false;
Key key = ((Key)x);
return this.firstId == key.firstId
&& this.secondId == key.secondId;
}
// implement hashCode as well
}
}
In the example above the inner class is static but that doesn't really matter. The only reason I set it that way is so that exterior classes could construct it. Make sure when you are overriding the .equals that you also get the .hashCode. They should change with each other.