Access instance property from enclosed class - java

I'm a newbie on java, in this example is it possible to get the id of ClassA from ClassB?
public class ClassA {
private Long id;
private List<ClassB> listOfClassB;
[...]
}
public class ClassB {
private Long num;
public boolean isValidRow() {
return this.num > ***ClassA.this.getId()***;
}
[...]
}

For getting the id field of ClassA, you need to have an instance of ClassA in ClassB, for example:
public class ClassA {
private Long id;
private List<ClassB> listOfClassB;
[...]
}
public class ClassB {
private Long num;
private ClassA a;
public ClassB(Long num, ClassA a) {
this.num = num;
this.a = a;
}
public boolean isValidRow() {
return this.num > a.getId();
}
[...]
}
And initiate it this way:
new ClassB(1, new ClassA(...));

Try the following:
public class ClassB {
private ClassA a;
private Long num;
public ClassB(ClassA a){
this.a=a;
}
public boolean isValidRow() {
return this.num > a.getId();
}
}
Use it as follows:
...
ClassA a = new ClassA();
ClassB b = new ClassB(a);
...
Or if you create Bs inside A:
ClassB b = new ClassB(this);

This will work for nested classes only:
class ClassA {
private long id;
class ClassB {
ClassA.this.getId(); // Will work here
}
}
To make it work in your case you need inject instance of ClassA to instance of ClassB:
class ClassA {
long id;
}
class ClassB {
private ClassA a;
ClassB(ClassA a) {
this.a = a;
}
void someMethod() {
long id = a.getId();
}
}

You cannot get the id of ClassA, but you can get it from instance of ClassA
For example:
ClassA a =new ClassA():
ClassB b =new ClassB(a);
ClassA:
public class ClassA{
private Integer id;
public Integer getId(){return id;}
}
ClassB:
public class B {
//whatever
private A a;
public B(A a){
this.a=a;
}
public void someMethod(){
//whatever
t.getId() // here you have the id.
}
}
now everywhere in your ClassB you will have access to a.getId().

Related

Unable to map target properties using constructors with mapstruct

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

#Inject Annotation of 2 constructors for 2 dependent classes in Java

Here is the code I am trying :
public class ClassA {
private final String check;
private final ClassB classB;
//ClassA constructor
#Inject
public ClassA(String check, ClassB classB) {
this.check = check + "A";
this.classB = classB;
}
public String getCheck() {
String check = classB.getCheck();
print(check) ///////////////return checkA
}
}
public class ClassB {
private final String check;
//ClassB constructor
#Inject
public ClassB(String check) {
this.check = check + "B";
}
public String getCheck() {
return check;
}
}
So, when #Inject is annotated for both the constructors, classB.getCheck(); should return checkB but it returns checkA. I assume this is because the classB constructor is not being executed due to #Inject annotations. But I am not sure of the exact reason. Any suggestion what I am missing?

Is it possible to get public static field from template class argument?

Given
class A {
public static A newInstance(int x) { ... }
}
And several classes containing static fields of type A
class B1 {
public static A MIN = A.newInstance(10);
}
class B2 {
public static A MIN = A.newInstance(15);
}
I would like to parameterize a class with B1 or B2 to get MIN field of type A from class B in the class C:
class C <T, P> {
private T t = ???;
}
When C<A, B1> c = new C(); what should be placed instead ??? to get B1.MIN?
Is it possible?
EDIT:
Thank you for the answers, I have upvoted both.
I have arrived simply at
class C <T, P> {
private T t;
public C(T min) {
this.t = min;
}
}
This will be just C<A, B1> c = new C<A, B1>(B1.MIN); because as you can see it is hard to avoid a constructor for C taking an instance of B1 or smth like that. But in this case B1 at least not instantiated.
You can use an interface to achieve this behavior:
class A {
public static A newInstance() { return new A(); }
}
interface HasMin {
public static A MIN = null;
}
class B1 implements HasMin {
public static A MIN = A.newInstance();
}
class B2 implements HasMin {
public static A MIN = A.newInstance();
}
class C<T extends HasMin> {
private A t = T.MIN;
}
Then you can create: C<B1> and C<B2> and use both.
As Tom suggested in the comments below, this approach is limited to use static fields. An even better approach would be:
public class Play {
public static void main(String[] args) {
B1 b1 = new B1();
C<B1> c = new C<>(b1);
System.out.println(c.getA()); // prints: A{ x=10 }
B2 b2 = new B2();
C<B2> c2 = new C<>(b2);
System.out.println(c2.getA()); // prints: A{ x=20 }
}
}
class A {
private int x;
public A(int x) {
this.x = x;
}
#Override
public String toString() {
return "A{ x=" + x + " }";
}
public static A newInstance(int x) {
return new A(x);
}
}
interface GetMin {
public A getMin();
}
class B1 implements GetMin {
public A MIN = A.newInstance(10);
#Override
public A getMin() {
return MIN;
}
}
class B2 implements GetMin {
public A MIN = A.newInstance(20);
#Override
public A getMin() {
return MIN;
}
}
class C<T extends GetMin> {
private A a = null;
public C(T t) {
a = t.getMin();
}
public A getA() {
return a;
}
}
I would forget static and have a concrete instance of an interface:
public interface Bounds<T> {
T min();
}
The concrete instance could be singleton, so next best thing to a static:
public enum B implements Bounds<A> {
INSTANCE;
private final A min = A.newInstance(10);
#Override
public A min() {
return min;
}
}
C then defined like so:
public class C<T, P extends Bounds<T>> {
private T min;
public C(P bounds) {
min = bounds.min();
}
public T getMin() {
return min;
}
}
Usage:
C<A, B> c = new C(B.INSTANCE);
Self describing
Maybe you don't want this meta data type (B), maybe you want types to describe themselves. So C could be defined for types that can describe their own bounds:
public class C<T extends Bounds<T>> {
private T min;
public C(T anyT) {
min = anyT.min();
}
public T getMin() {
return min;
}
}
Usage:
C<A> c = new C(A.zero); //any A will do
Where A is:
public class A implements Bounds<A>{
public final static A zero = A.newInstance(0);
private final static A min = A.newInstance(10);
public static A newInstance(int x) {
return new A(x);
}
private int x;
public A(int x) {
this.x = x;
}
#Override
public A min() {
return min;
}
}

simple-framework - how to pass member to super class

I'm trying to serialize a simple hierarchy:
public class RootClass {
#Element
private final int a;
public RootClass( int a) {
this.a = a;
}
}
class SubClass extends RootClass {
#Element(name="b")
int b;
public SubClass() {
super(0);
this.b=0;
}
}
when I run
SubClass sub = new SubClass();
Serializer serializer = new Persister();
StringBuilderWriter writer = new StringBuilderWriter(1000);
serializer.write(sub, writer);
I get:
ConstructorException: Default constructor can not accept read only
#org.simpleframework.xml.Element(name=, data=false, type=void, required=true)
on field 'a' private final int
com.informatica.b2b.structurediscovery.serialization.tests.RootClass.a in class
com.informatica.b2b.structurediscovery.serialization.tests.SubClass
I couldn't find any way to make it work.
What is Serializer? if you want to serialize your object, you should implement the interface Serializable. Here is my code:
public class RootClass implements Serializable{
private final int a;
public RootClass(int a) {
this.a = a;
}
public void print(){
System.out.println(a);
};
}
public class SubClass extends RootClass {
int b;
public SubClass() {
super(0);
this.b = 0;
}
public void print() {
super.print();
}
}
SubClass sub = new SubClass();
sub.print();
try {
File file = new File("SubClass");
if (!file.exists())
file.createNewFile();
FileOutputStream fileOut = new FileOutputStream(file);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(sub);
out.close();
fileOut.close();
} catch (IOException i) {
i.printStackTrace();
}
You need to pass in the value for a like so.
class SubClass extends RootClass {
#Element(name="b")
int b;
public SubClass(#Element(name="a")int a) {
super(a);
this.b=0;
}
}
Or try this
class SubClassSubstitute {
#Element
int a;
#Element
int b
public SubClassSubstitute(#Element(name="a")int a, #Element(name="b")int b){
this.a = a;
this.b = b;
}
#Resolve
public SubClass resolve() {
return new Subclass(a)
}
}
class SubClass extends RootClass {
#Element(name="b")
int b;
public SubClass(#Element(name="a")int a) {
super(a);
this.b=0;
}
public SubClassDelegate replace() {
return new SubClassSubstitute(a, b);
}
}
The above works the same as readResolve() and writeReplace() in java object

JAXB Can't handle interfaces

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;
}

Categories