How to deal with arrays of static objects? - java

I'm having an issue dealing with static object types in a parser I'm writing.
glob = new func("glob");
glob.addChild(new func("wrong"));
System.out.println(glob.name);
func is a static class that I'm referencing in the above code within main. When this code is run, the printed text is "wrong". I'm assuming that making func static as I did is causing there to only ever be one func allowed, and it's being overwritten since I can't create instances of func. Is there a way around this? Here's part of the code for the declaration of func for reference
static class func{
public func (String name){
//etc
}
}
This is becoming an issue because I want to be able to create a nest of these objects to use for determining scope within a parser. func would have children, and the idea was that a child node could look for a 'variable' (here just a string) that I add first within itself, then within its parent, and so on down the line. Creating children just overwrited the parent though.
Update: People wanted more code from func
static class func{
public static func[] children;
public String name;
public static func parent;
private static int child_index, var_index;
private static String[][] vars;
public func (String name, func parent){
children = new func[50];
//etc
}
}
You're right that I did have a static name. If I remove that, my worry is that the vars/children arrays will still continue to be overwritten, and removing those gives me a lot of 'non-static variables cannot be referenced...' messages.

The static modifier on a class doesn't do the same thing as static on other entities. First of all, you can't apply static to a top-level class at all. It's only useful for a class defined inside another class:
public class Outer {
public class Inner {
...
}
static public class Nested {
...
}
}
The difference is that whenever you create an object of class Inner, the object "belongs", in a sense, to some object of an Outer class. The Inner object contains a reference to some Outer object, and its methods can reference fields of the Outer object to which it belongs.
The Nested class, however, is more like a top-level class; the main difference is that outside classes can refer to it as Outer.Nested, which can be useful when you want several different nested classes all named Nested. It's a way to avoid "polluting the namespace" with top-level class names, and to make it clear that a Nested is somehow closely related to an Outer. Also, because of Java's rules about visibility, a Nested class's methods can access private members of Outer, which an outside top-level class can't do.
But it doesn't mean you can create only one Nested. If you want a class that can have only one object, use a singleton pattern. (But also think about whether you really want to do this and why; singleton patterns are disdained by some programmers, probably because they look too much like global variables, which reduces the flexibility to make certain kinds of changes to your program in the future.) (P.S. After trying to read your question more carefully, I'm not sure that a singleton is what you want, and in fact I'm not clear at all on what your design is supposed to look like.)

It is meant to be so, since a static variable is a variable owned by a Class and not instances of that Class and it is so for inner static classes.
Otherwise I can't see how did you manage to make your func class static since as far as I know Java do not allow Top-level classes to be static and only inner classes can be so.
I can't see clearely what you are aiming to achieve but you should reconsider your design. Maybe with better explanation someone could bring some help.

Related

Why private members of nested class are accessible in outer class [duplicate]

I observed that Outer classes can access inner classes private instance variables. How is this possible? Here is a sample code demonstrating the same:
class ABC{
class XYZ{
private int x=10;
}
public static void main(String... args){
ABC.XYZ xx = new ABC().new XYZ();
System.out.println("Hello :: "+xx.x); ///Why is this allowed??
}
}
Why is this behavior allowed?
The inner class is just a way to cleanly separate some functionality that really belongs to the original outer class. They are intended to be used when you have 2 requirements:
Some piece of functionality in your outer class would be most clear if it was implemented in a separate class.
Even though it's in a separate class, the functionality is very closely tied to way that the outer class works.
Given these requirements, inner classes have full access to their outer class. Since they're basically a member of the outer class, it makes sense that they have access to methods and attributes of the outer class -- including privates.
If you like to hide the private members of your inner class, you may define an Interface with the public members and create an anonymous inner class that implements this interface. Example bellow:
class ABC{
private interface MyInterface{
void printInt();
}
private static MyInterface mMember = new MyInterface(){
private int x=10;
public void printInt(){
System.out.println(String.valueOf(x));
}
};
public static void main(String... args){
System.out.println("Hello :: "+mMember.x); ///not allowed
mMember.printInt(); // allowed
}
}
The inner class is (for purposes of access control) considered to be part of the containing class. This means full access to all privates.
The way this is implemented is using synthetic package-protected methods: The inner class will be compiled to a separate class in the same package (ABC$XYZ). The JVM does not support this level of isolation directly, so that at the bytecode-level ABC$XYZ will have package-protected methods that the outer class uses to get to the private methods/fields.
There's a correct answer appearing on another question similar to this:
Why can the private member of an nested class be accessed by the methods of the enclosing class?
It says there's a definition of private scoping on JLS - Determining Accessibility:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Thilo added a good answer for your first question "How is this possible?". I wish to elaborate a bit on the second asked question: Why is this behavior allowed?
For starters, let's just be perfectly clear that this behavior is not limited to inner classes, which by definition are non-static nested types. This behavior is allowed for all nested types, including nested enums and interfaces which must be static and cannot have an enclosing instance. Basically, the model is a simplification down to the following statement: Nested code have full access to enclosing code - and vice versa.
So, why then? I think an example illustrate the point better.
Think of your body and your brain. If you inject heroin into your arm, your brain gets high. If the amygdala region of your brain see what he believe is a threat to your personally safety, say a wasp for example, he'll make your body turn the other way around and run for the hills without You "thinking" twice about it.
So, the brain is an intrinsic part of the body - and strangely enough, the other way around too. Using access control between such closely related entities forfeit their claim of relationship. If you do need access control, then you need to separate the classes more into truly distinct units. Until then, they are the same unit. A driving example for further studies would be to look at how a Java Iterator usually is implemented.
Unlimited access from enclosing code to nested code makes it, for the most part, rather useless to add access modifiers to fields and methods of a nested type. Doing so is adding clutter and might provide a false sense of safety for new comers of the Java programming language.
An IMHO important use case for inner classes is the factory pattern.
The enclosing class may prepare an instance of the inner class w/o access restrictions and pass the instance to the outside world, where private access will be honored.
In contradiction to abyx declaring the class static doesn't change access restrictions to the enclosing class, as shown below. Also the access restrictions between static classes in the same enclosing class are working. I was surprised ...
class MyPrivates {
static class Inner1 { private int test1 = 2; }
static class Inner2 { private int test2 = new Inner1().test1; }
public static void main(String[] args) {
System.out.println("Inner : "+new Inner2().test2);
}
}
Access restrictions are done on a per class basis. There is no way for a method declared in a class to not be able to access all of the instance/class members. It this stands to reason that inner classes also have unfettered access to the members of the outer class, and the outer class has unfettered access to the members of the inner class.
By putting a class inside another class you are making it tightly tied to the implementation, and anything that is part of the implementation should have access to the other parts.
The logic behind inner classes is that if you create an inner class in an outer class, that's because they will need to share a few things, and thus it makes sense for them to be able to have more flexibility than "regular" classes have.
If, in your case, it makes no sense for the classes to be able to see each other's inner workings - which basically means that the inner class could simply have been made a regular class, you can declare the inner class as static class XYZ. Using static will mean they will not share state (and, for example new ABC().new XYZ() won't work, and you will need to use new ABC.XYZ().
But, if that's the case, you should think about whether XYZ should really be an inner class and that maybe it deserves its own file. Sometimes it makes sense to create a static inner class (for example, if you need a small class that implements an interface your outer class is using, and that won't be helpful anywhere else). But at about half of the time it should have been made an outer class.
Inner class is regarded as an attribute of the Outer class. Therefore, no matter the Inner class instance variable is private or not, Outer class can access without any problem just like accessing its other private attributes(variables).
class Outer{
private int a;
class Inner{
private int b=0;
}
void outMethod(){
a = new Inner().b;
}
}
Because your main() method is in the ABC class, which can access its own inner class.

Making everything non-static

As a form of habit, I typically avoid keeping things in static methods for testing and for ease-of-use down the line in my java projects. However, in the past I have had to use a messy mix of static and non-static methods revolving around my main class, because I only know of one way to create a non-static instance of the class. Typically, I do this as a global variable, rather than load the class methods in each method.
For an example, let's say I have class MainGUI and ProjMain. In ProjMain, I use the global variable:
private MainGUI gui = new MainGUI();
This works very well, however if I have methods within the ProjMain class I want to access from the MainGUI class, naturally I go to do the same.
private ProjMain project = new ProjMain();
In this, I create a StackOverflowError. Is there a simple way to get the instance of the class as a variable, without having to put the variable in individual methods as opposed to global methods?
Hovercraft's solution is pretty good, here i have another one for you:
If you have lots of classes reference to each other, you should consider to extract a higher layer for them, the higher layer class should looks like this:
class HigherLayer {
public void dosomething(ProjMain pm, MainGUI mg){
pm.hello(mg);
mg.bye(pm);
}
}
And remove the global variables from ProjMain and MainGUI to make them less coupling.
Your classes have references to each other, and this is OK, but not if each creates a new reference to the other since this will do nothing but cause an infinite recursion with one creating an instance of the other, which creates an instance of the first, which creates an instance of the other, which creates an instance of the first, which creates an instance of the other, ..... etc...
To solve this, have one object create the other, but simply pass a reference to itself into the other via it's constructor or a setter method.
For example, the first class:
public class FirstClass {
private SecondClass secondClass;
public FirstClass() {
secondClass = new SecondClass(this);
}
and the other class
public class SecondClass {
private FirstClass firstClass;
public FirstClass(FirstClass firstClass) {
this.firstClass = firstClass;
}

Is there an info-graphic that explains java variable inheritance and constructor code flow?

Is there an info-graphic that explains java variable inheritance and constructor code flow?
I'm having troubles visualizing how inheritance and class variables work, public, static private default or otherwise.
The Java Tutorials from Oracle have a section all about Inheritance and should be able to answer most of your questions.
I would refer you to go with Lava Language Specification and try to write the code using above keywords and then test it.
default: Visible to the package. .
private: Visible to the class only
public: Visible to the world
protected: Visible to the package and all subclasses .
The access modifier (public, protected, package) plays only a small role in inheritance. You can't make a function or variable in a subclass less accessible than the superclass (e.g., Animal has public void doStuff() and Cat extends Animal has private void doStuff()
Static and non-static methods don't really affect inheritance either. Static variables work the same way, except relative to the class of interest
public class Magic{
public static int pants;
}
public class MagicPants extends Magic{
public void go(){
System.out.println(pants);
System.out.println(MagicPants.pants);
System.out.println(Magic.pants);
}
public static void main(String argv[]){
Magic.pants = 2;
MagicPants.pants = 1;
new MagicPants().go();
}
}
All print 1
Constructor code flow is easy - follow the super() calls.
So i don't know graphics.
Static means the variable is the same for all object which have the same class.
Like
public Class TryVariable{
public static int variable = 2
public static void main(String[] args){
a = new TryVariable()
b = new TryVariable()
system.out.println(a.variable)
system.out.println(b.variable)
// both equals 2
a.variable= 3
system.out.println(a.variable)
system.out.println(b.variable)
// both equals 3, because variable is static.
}
Public variable means you can directly change directly her by the way i do in ma previous example: object.variableName = value.
This is dangerous, all people inadvisable to use it.
Private variable can't be change directly you need to use somes getters and setters to do this work. It's is the good way to code.
The defaut, i'm not sur of all parameters so i don't describe to you. But 99.9% of time the private is use.
Protected mean, the variable is open to packages and sub classes (in first time private is easier to use and safer)
An other parameter can be final, with this parameter the variable can't be change any more. It's like a constant. And a static final parameter is a class constant.
If you need more information, previous response explain where are find the officials sources.
This is very easy example: http://vskl.blogspot.cz/2009/05/polymorphism-in-java.html
every time you create Circle or Square object, Shape object is created too
About the variables:
- private fields are not accessible by any other class including subclasses.
- protected fields are accessible by any subclass. Taken the picture from the link, variables x and y of abstract class Shape, every instance of Circle or Square have these fields.
- default fields are accessible by any subclass and by any class in the same package(only in same package, classes in subpackages do not have access). This is useful typicaly when writing automated test, you don't have to declare public getter for the field.
- public fields are accessible by any other class. However using those is not a clean way how to write code, it is better to create private field with getter and setter.
- static keyword designates field owned by class, not by it's instances. It is like having one field shared by multiple instances of the class. If one instance changes value of this field, every other instance can read only this new modified

Java member object inside class of same type

I am looking at a codebase and I often see something like:
public class SomeClass
{
protected static SomeClass myObject;
//...
public static SomeClass getObject()
{
return myOjbect
}
}
I'd like to make sure I understand the purpose behind this. Is it to ensure one instance of the class gets shared even if it is instantiated multiple times? I am not sure about the vocabulary here, or else I'd search for the answer, so if this pattern has a name, please let me know.
Also, this seems a little chicken-and-egg definition because the class includes an object of the type of the class. Why isn't this actually paradoxical?
Thanks!
This is really only common with the Singleton Pattern where there is only this one instance of the class. While it has its uses, Singleton is over- and misused more often than not (usually to disguise procedural programming as OO). It also occurs very often in example code for Java AWT or Swing, where you typically subclass Frame / JFrame, and create an instance in a main method inside the same class.
Also, this seems a little
chicken-and-egg definition because the
class includes an object of the type
of the class. Why isn't this actually
paradoxical?
Why do you think it is? The class mainly describes what members instances of this type have - but a static member does not belong to an instance, it belongs to the class itself, so it doesn't have anything to do with the "blueprint" role of the class. Static members are really somewhat un-OO because of that.
But even on the instance level you can have references of the same type. For example, an entry in a linked list would typically have two references to the next and previous entries, which are of the same class.
This is called the Singleton design pattern.
You are correct in stating that the purpose is to ensure only one instance of the class gets created.
Wikipedia has a preyty good article on the pattern.
The pattern you mentioned is called "Singleton", but from your code sample it is not clear if this is really what is intended. Due to the fact that the member is protected, I would guess not - if there are subclasses, then there would probably not be a single instance.
It's called Singleton. You ensure the creation of just ONE (1) object of a given class.
You should add a private Constructor, so the only one who create the object is the class.
public class SomeClass
{
// Using private constructor
protected static SomeClass myObject = new SomeClass();
private SomeClass(){
//...
}
public static SomeClass getObject()
{
return myOjbect
}
}
Much much more here, in Wikipedia
You may want to take a look to Factory Pattern
It's not all that uncommon; it can be a good way to implement the Singleton pattern. There can be other uses as well - sometimes you will want a handful - and no more - of objects of a given class; that class is a good place to hang onto them. In the event that you don't want other classes to be able to create objects of this class, it is common to give the class a private constructor as well.
It's not paradoxical, because the compiler can be aware of a reference to the class before it has fully compiled the class. Later - if you like to think of it this way - it can "fill in the blanks".

Why can outer Java classes access inner class private members?

I observed that Outer classes can access inner classes private instance variables. How is this possible? Here is a sample code demonstrating the same:
class ABC{
class XYZ{
private int x=10;
}
public static void main(String... args){
ABC.XYZ xx = new ABC().new XYZ();
System.out.println("Hello :: "+xx.x); ///Why is this allowed??
}
}
Why is this behavior allowed?
The inner class is just a way to cleanly separate some functionality that really belongs to the original outer class. They are intended to be used when you have 2 requirements:
Some piece of functionality in your outer class would be most clear if it was implemented in a separate class.
Even though it's in a separate class, the functionality is very closely tied to way that the outer class works.
Given these requirements, inner classes have full access to their outer class. Since they're basically a member of the outer class, it makes sense that they have access to methods and attributes of the outer class -- including privates.
If you like to hide the private members of your inner class, you may define an Interface with the public members and create an anonymous inner class that implements this interface. Example bellow:
class ABC{
private interface MyInterface{
void printInt();
}
private static MyInterface mMember = new MyInterface(){
private int x=10;
public void printInt(){
System.out.println(String.valueOf(x));
}
};
public static void main(String... args){
System.out.println("Hello :: "+mMember.x); ///not allowed
mMember.printInt(); // allowed
}
}
The inner class is (for purposes of access control) considered to be part of the containing class. This means full access to all privates.
The way this is implemented is using synthetic package-protected methods: The inner class will be compiled to a separate class in the same package (ABC$XYZ). The JVM does not support this level of isolation directly, so that at the bytecode-level ABC$XYZ will have package-protected methods that the outer class uses to get to the private methods/fields.
There's a correct answer appearing on another question similar to this:
Why can the private member of an nested class be accessed by the methods of the enclosing class?
It says there's a definition of private scoping on JLS - Determining Accessibility:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Thilo added a good answer for your first question "How is this possible?". I wish to elaborate a bit on the second asked question: Why is this behavior allowed?
For starters, let's just be perfectly clear that this behavior is not limited to inner classes, which by definition are non-static nested types. This behavior is allowed for all nested types, including nested enums and interfaces which must be static and cannot have an enclosing instance. Basically, the model is a simplification down to the following statement: Nested code have full access to enclosing code - and vice versa.
So, why then? I think an example illustrate the point better.
Think of your body and your brain. If you inject heroin into your arm, your brain gets high. If the amygdala region of your brain see what he believe is a threat to your personally safety, say a wasp for example, he'll make your body turn the other way around and run for the hills without You "thinking" twice about it.
So, the brain is an intrinsic part of the body - and strangely enough, the other way around too. Using access control between such closely related entities forfeit their claim of relationship. If you do need access control, then you need to separate the classes more into truly distinct units. Until then, they are the same unit. A driving example for further studies would be to look at how a Java Iterator usually is implemented.
Unlimited access from enclosing code to nested code makes it, for the most part, rather useless to add access modifiers to fields and methods of a nested type. Doing so is adding clutter and might provide a false sense of safety for new comers of the Java programming language.
An IMHO important use case for inner classes is the factory pattern.
The enclosing class may prepare an instance of the inner class w/o access restrictions and pass the instance to the outside world, where private access will be honored.
In contradiction to abyx declaring the class static doesn't change access restrictions to the enclosing class, as shown below. Also the access restrictions between static classes in the same enclosing class are working. I was surprised ...
class MyPrivates {
static class Inner1 { private int test1 = 2; }
static class Inner2 { private int test2 = new Inner1().test1; }
public static void main(String[] args) {
System.out.println("Inner : "+new Inner2().test2);
}
}
Access restrictions are done on a per class basis. There is no way for a method declared in a class to not be able to access all of the instance/class members. It this stands to reason that inner classes also have unfettered access to the members of the outer class, and the outer class has unfettered access to the members of the inner class.
By putting a class inside another class you are making it tightly tied to the implementation, and anything that is part of the implementation should have access to the other parts.
The logic behind inner classes is that if you create an inner class in an outer class, that's because they will need to share a few things, and thus it makes sense for them to be able to have more flexibility than "regular" classes have.
If, in your case, it makes no sense for the classes to be able to see each other's inner workings - which basically means that the inner class could simply have been made a regular class, you can declare the inner class as static class XYZ. Using static will mean they will not share state (and, for example new ABC().new XYZ() won't work, and you will need to use new ABC.XYZ().
But, if that's the case, you should think about whether XYZ should really be an inner class and that maybe it deserves its own file. Sometimes it makes sense to create a static inner class (for example, if you need a small class that implements an interface your outer class is using, and that won't be helpful anywhere else). But at about half of the time it should have been made an outer class.
Inner class is regarded as an attribute of the Outer class. Therefore, no matter the Inner class instance variable is private or not, Outer class can access without any problem just like accessing its other private attributes(variables).
class Outer{
private int a;
class Inner{
private int b=0;
}
void outMethod(){
a = new Inner().b;
}
}
Because your main() method is in the ABC class, which can access its own inner class.

Categories

Resources