Mistu4u
Mistu4u

Reputation: 5416

Initialize a class having another class object as member variable

This is my first class:

package trickycorejava;

public class InnerClass {
    int id;
    oneClass oneClass;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public trickycorejava.oneClass getOneClass() {
        return oneClass;
    }

    public void setOneClass(trickycorejava.oneClass oneClass) {
        this.oneClass = oneClass;
    }

    public InnerClass(int id, trickycorejava.oneClass oneClass) {
        this.id = id;
        this.oneClass = oneClass;
    }
    public InnerClass(int id){
        this.id = id;
    }
}

class oneClass {
    private String name;

     public String getName() {
        return name;
     }

     public void setName(String name) {
        this.name = name;
    }
}

This is the class where the main method exists, observe that the package is different:

package trickycorejava.constructor;

import trickycorejava.InnerClass;

public class InnerClassTest {
    public static void main(String[] args) {
        InnerClass innerClass = new InnerClass(1);
    }

}

How can I initialize the InnerClass with constructor in this case? If I use

InnerClass innerClass = new InnerClass(1, new oneClass("Test"));

I get the error that oneClass is not public cannot be access from outside package.

Upvotes: 0

Views: 524

Answers (1)

Balázs Eszes
Balázs Eszes

Reputation: 166

As Turing85 pointed out the oneClass should be in it's own file, otherwise it's going to be package-private which means you can only access it from classes of the same package.

Is there another way? There is, but it's not going to be a simple constructor call. Using reflection you can bypass class, field and method invocation protection.

public class InnerClassTest {
    public static void main(String[] args) throws Exception {
        Constructor<OneClass> constructor = OneClass.class.getDeclaredConstructor(String.class);
        constructor.setAccessible(true);
        OneClass instance = constructor.newInstance("John");
        InnerClass innerClass = new InnerClass(1, instance);
    }
}

What this does is that it finds the constructor that is private to Main because the class is package-private. Then it disables the protection of it, note that these are temporary, the Constructor object is a new reference and only allows the invocation via this reference.

But I don't recommend doing this extensively. Reflection has some use cases, mainly to aid programmers in frameworks like Spring, but otherwise it can break object oriented patterns.

Upvotes: 2

Related Questions