How Can a Class Have a Member of Its Own Type, Isn't This Infinite Recursion

How can a class have a member of its own type, isn't this infinite recursion?

You're only declaring the variable and not creating it. Try creating it at declaration or in the constructor and let me know what happens:

public class Abc {
private Abc p = new Abc(); // have fun!

public static void main(String[] args) {
new Abc();
}
}

Incidentally, if you don't create it in the class, but rather accept a reference to it in a getter method or a constructor parameter, your code will work just fine. This is how some linked lists work.

Can a class have a member of its own type?

Can a class have a member of its own type?

Sure. It's actually quite common. Think of the case of a node in a linked list for instance:

class Node {
Node next;
int value;
}


How should I build the constructor(s) for this class?

You have several options (see below). You should obviously avoid creating new instances of the class in each invocation of the constructor as it would result in an infinite recursion.

  • You could take a Node as argument and initialize it like

    this.next = nextArg;
  • You could initialize it to the null-reference

    this.next = null;
  • You could initialize it to this

    this.next = this;

(It's generally a bad idea to create a whole object graph inside a constructor any way so I wouldn't worry about this anyway :-)

a class type object as member/instance variable in the same class

The code you have posted is the implementation of a linked list. The way the nodes of the linked list work is each node in the list contains its data (in your case: int val) and also a reference to the next node in the list. Then the again, the next node will contain a reference to its next node. This goes on until the last element of the list, for which the next node is null.

This allows each element/node of the linked list (ListNode object) to be stored at random locations unlike arrays where elements are stored one after the other in consecutive memory locations.

So you would use your ListNode class like this:

ListNode last  = new ListNode(3);
ListNode second = new ListNode(2, last);
ListNode first = new ListNode(1, second);

The three objects above may be stored at different memory locations not necessarily consecutive to each other. But it does not matter because you can access the next element of the list using the next instance variable:

ListNode second = first.next;
ListNode last = first.next.next;
//OR
ListNode last = second.next

However, in Java, you would usually not access an instance variable directly, you would use a getter and setter:

public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
public ListNode getNext() { return next; }
public ListNode setNext(ListNode next) { this.next = next; }
public int getVal() { return val; }
}

Now, creating the list is much easier:

ListNode first = new ListNode(1);
ListNode second = new ListNode(2);
ListNode third = new ListNode(3);
first.setNext(second);
second.setNext(third);

// Now you could traverse the list and print the elements as follows:
ListNode element = first;
while(element != null) {
System.out.println(element.getVal())
element = element.getNext();
}

Output
Let me know if you still have anything that is unclear.

JSON Jackson Infinite Recursion Error Java

Managed to fix the issue by using

@JsonIgnore

From the EclipseLink JPA, on the Shift object. This caused the recursive loop to break, solving the issue.

Infinite Recursion with Jackson JSON and Hibernate JPA issue

You may use @JsonIgnore to break the cycle (reference).

You need to import org.codehaus.jackson.annotate.JsonIgnore (legacy versions) or com.fasterxml.jackson.annotation.JsonIgnore (current versions).

Is this static? Checking for Static in the constructor

Updated Answer:

In OP's very specific preferred approach there's no point. The public Thing NonStaticThing = new("NonStaticThing"); will result in a StackOverflowException as each child will try to create another child infinitely.

In general, however, my advice to anybody trying to do something "statically" and otherwise "not" would be to use a static constructor for static things.

Original Answer based upon un-edited question:

Order of operations - The static field will be assigned before anything else outside that class can call the constructor on that class and the constructor for setting that static readonly field will be called before the static field is actually assigned. Simply check to see if the static field is null in your constructor.

private static void Main(string[] args)
{
var test = new Thing();
Console.WriteLine(test.IsStaticInstance); // False
Console.WriteLine(Thing.Instance.IsStaticInstance); // True
}

public class Thing
{
public static readonly Thing Instance = new Thing();
public Thing()
{
IsStaticInstance = Instance == null;
}
public bool IsStaticInstance { get; }
}


Related Topics



Leave a reply



Submit