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 likethis.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
Fastest Way to Iterate Over All the Chars in a String
How to Format a Java String with Leading Zero
How to Merge Two PDF Files into One in Java
How to Keep a Scanner from Throwing Exceptions When the Wrong Type Is Entered
Using Itextpdf to Trim a Page's Whitespace
How Do Java Interfaces Simulate Multiple Inheritance
Check Whether Number Is Even or Odd
Is There a Difference Between Single and Double Quotes in Java
How to Initialize an Array of Objects in Java
What's Alternative to Singleton
Are "While(True)" Loops So Bad
How to Schedule a Task to Run at Periodic Intervals
What Is the Cross-Platform Way of Obtaining the Path to the Local Application Data Directory
Java:Non-Static Variable Cannot Be Referenced from a Static Context Error