LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-27-2009, 08:34 AM   #1
irey
Member
 
Registered: Jun 2008
Location: Torino, Italy
Posts: 66

Rep: Reputation: 17
Java: what's the difference between an inner class and a static inner class?


Hi everyone,

I've read the java language specification 100 times but I still don't understand this detail. If I declare an inner class like this:
Code:
public class Trie {
    private class TrieNode {
        //...
    }
    //...
}
What's the difference if TrieNode is declared static?

This curiosity arose cause I'm using a code analyzer (findbugs) to get some more warnings and try to write cleaner code. It suggested making the inner class static to improve performance. (?)
 
Old 01-27-2009, 09:06 AM   #2
indienick
Senior Member
 
Registered: Dec 2005
Location: London, ON, Canada
Distribution: Arch, Ubuntu, Slackware, OpenBSD, FreeBSD
Posts: 1,853

Rep: Reputation: 65
When you declare something, in Java, as "static" it is only created once, in the running virtual machine image.

For example - your inner class TrieNode. In your example it's a regular inner class. Every time a chunk of code within Trie creates a new TrieNode object, a new instance of that object is created.

Now, should you declare it static (which I do not recommend, in your case)...well, to put it simply, that portion of your program won't work. Static declarations means it is - simply - created once, and only once; static classes cannot have a constructor. An example of a static class would be the java.lang.System class. Static declarations limit that item to only existing once; useful for things like enumerations and constants - data that may change but does not need to be re-made.

And, unless I am mistaken, you do not actually declare a class static, just the elements within it.

An example for where you might use a static declaration:
Code:
[i]/* Constants and functions for doing calculations for CNC machining */[i]
public class CNCMath {
  /* Millimeters to inches conversion ratios and function */
  static final float MMTOINRATIO = 0.039370078;
  static float millimetersToInches(int mm) { return (mm * MMTOINRATIO); }
  static float millimetersToInches(float mm) { return (mm * MMTOINRATIO); }

  /* Inches to millimeters stuff */
  static final float INTOMMRATIO = 25.4;
  static float inchesToMillimeters(int inch) { return (in * INTOMMRATIO); }
}
Then, when I want to get a value from either of those (trivial) functions, I just go (assuming I have a variable - cm - of type "CNCMachine" defined somewhere, already):
Code:
...
cm.move(X_AXIS, CNCMath.millimetersToInches(83));
...

Last edited by indienick; 01-27-2009 at 09:13 AM.
 
Old 01-27-2009, 10:05 AM   #3
irey
Member
 
Registered: Jun 2008
Location: Torino, Italy
Posts: 66

Original Poster
Rep: Reputation: 17
Yes, I already knew about static members and static methods. In practice it means that a static member can be accessed just by the class name and no instance is required.

But now I realised that 'static' does not only apply to methods and members: an inner class can be declared static too. My program compiles and runs cleanly, but I don't know what changes.

Anyway I looked at the java sources and System is not a static class, it's just a normal class with static methods.
 
Old 01-27-2009, 10:10 AM   #4
indienick
Senior Member
 
Registered: Dec 2005
Location: London, ON, Canada
Distribution: Arch, Ubuntu, Slackware, OpenBSD, FreeBSD
Posts: 1,853

Rep: Reputation: 65
Quote:
Originally Posted by irey
Anyway I looked at the java sources and System is not a static class, it's just a normal class with static methods.
Sorry about that misinformation.

In that case, I do not know what the difference would be. I do not know in down-'n-dirty info on how Java handles stacks and heaps, but I wonder if the difference is analogous to C++ where creating a new class by object or by reference to an object? (I do not know C++, so maybe I am just blowing wind, here.)

EDIT: I found this link - http://www.javaworld.com/javaworld/j...a-static2.html - I don't know if it will help you, or not.

Last edited by indienick; 01-27-2009 at 11:23 AM.
 
Old 01-27-2009, 12:42 PM   #5
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
The main difference between a static and non-static inner class is that a non-static inner class has a sort of secondary implicit "this" to an instance of the outer class and therefore can access member data of the outer class or call member methods. This also means that you cannot create a non-static inner class independently from an outer class, which can be problematic in some cases. I personally recommend that you always make an inner class static unless you must have access to the outer class' members.
 
Old 01-27-2009, 09:18 PM   #6
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Rep: Reputation: 133Reputation: 133
Here is one of my early experiments. It contrasts two cases, one involving a non-static inner class and the other a static one. I hope it makes some sense.


Code:
class Outer{
    
    //inside the outer class, one can refer to inner class directly (outside Outer class, one will need to qualify using name of outer class - see OtherOuter class)
    public Inner inner = new Inner();
    
    private int val = 10;

    //non-static inner cannot exist on its own; it requires that an instance of Outer exist first
    class Inner{    
        
        private int val = 20;
        
        public Outer getOuter(){
            //the outer instance can be called using the dot notation (Outer.this)
            return Outer.this;
            }
            
        public Inner getSelf(){
            //inner class can refer to itself using regular "this"
            return this;
            }
            
        public int getOuterVal(){
            // use dot.this notation to refer to "val" member of outer class
            // as Inner is non-static, outer member "val" does not need to be static itself
            return Outer.this.val;
            }

        public int getOwnVal(){
            //and plain "val" to refer to its own val member
            return val;
            }    

        //non-static inner class cannot contain static inner classes; this is only possible in static inner classes; uncomment to see error message    
        //static class Nested{}    
        
        //but non-static inner classes are OK    
        class OtherNested{}    
        }
    
    //alternative method of producing an instance of the inner class    
    public Inner getInner(){
        return inner;
        }        
    
    }
    
class OtherOuter{
    
    //same as previous 
    public OtherInner oi = new OtherInner();
    
    //this HAS to be made static if it is to be accessed from the static inner class - a static inner class can refer to static members of outer class only
    //(unless, of course, one creates a new instance of the outer class inside the inner class)
    private  static int val = 10;
    
    static class OtherInner{
        
        private int val = 20;
        
        public OtherOuter getOtherOuter(){
            // a static class exists on its own, i.e. it has no connection whatsoever to any outer class
            // as a consequence, one cannot refer to the outer class using the dot.this notation but one has to create a new instance of it
            return new OtherOuter();
            //return OtherOuter.this;  /*this will not work; uncomment to see the error*/ 
            }
            
        public OtherInner getSelf(){
            return this;
            }

        public int getOuterVal(){
            // dot.this notation is illegal in inner class so we need an alternative way to access outer class member val
            return new OtherOuter().val;
            }

        public int getOwnVal(){
            return val;
            }    
        
        //static inner class can contain static inner classes itself    
        static class Nested{}    
        }
        //as well as non-static inner classes
        class OtherNested{}
        
    public OtherInner getOtherInner(){
        return oi;
        }    
    }    
    
public class InnerTest{
    
    public static void main (String [] args){
        
        //must create instance of Outer first
        Outer outer = new Outer();
        //only then can an instance of the inner class be created
        Outer.Inner inner = outer.new Inner();
        //alternative approach; still requires an instance of Outer
        Outer.Inner inner2 = outer.getInner();
        //get reference to outer from the inner class
        Outer outer2 = inner.getOuter();
        //and compare to the outer instance we created directly; they are the same
        System.out.println(outer ==outer2);
        
        //notice the syntax here: instance of inner can be created without creating an instance of the outer class first
        OtherOuter.OtherInner altIn = new OtherOuter.OtherInner();
        //now we can create an intance of outer from the inner class
        OtherOuter altOut = altIn.getOtherOuter();
        }
        
        
    }

Last edited by jay73; 01-27-2009 at 09:22 PM.
 
Old 01-28-2009, 03:34 AM   #7
irey
Member
 
Registered: Jun 2008
Location: Torino, Italy
Posts: 66

Original Poster
Rep: Reputation: 17
Thanks a lot to everyone. It's quite clear now.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to initialize a static array of a class in a static member function lali.p Programming 9 02-16-2008 09:27 AM
C++ templated Node class: pointers to different instantated class types jhwilliams Programming 3 08-20-2007 06:20 PM
Does derivated class inherit base class destructor (constructor)? kornerr Programming 2 08-23-2006 08:05 AM
C++: difference between static method variable and static class variable? Thinking Programming 3 01-16-2006 10:08 AM
Running a Java executable class from another executable class LUB997 Programming 22 07-24-2005 04:57 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:20 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration