Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 12 of 12

Thread: Nested classes.

  1. #1
    Junior Member
    Join Date
    Apr 2012
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Question Nested classes.

    Hi there!!

    I'm learning now Java and I just studied about Nested classes and their various types.
    Inside the tutorial, the author bring an example of implementation of nested class of the type "Inner classes".

    I want to quote here the code example and to ask on a specific section of it.

    Here's the code example:

    The DataStructure class below consists of:
    The DataStructure outer class, which includes methods to add an integer onto the array and print out values of even indices of the array.
    The InnerEvenIterator inner class, which is similar to a standard Java iterator. Iterators are used to step through a data structure and typically have methods to test for the last element, retrieve the current element, and move to the next element.
    A main method that instantiates a DataStructure object (ds) and uses it to fill the arrayOfInts array with integer values (0, 1, 2, 3, etc.), then calls a printEven method to print out values of even indices of arrayOfInts.

    public class DataStructure {
    // create an array
    private final static int SIZE = 15;
    private int[] arrayOfInts = new int[SIZE];

    public DataStructure() {
    // fill the array with ascending integer values
    for (int i = 0; i < SIZE; i++) {
    arrayOfInts[i] = i;
    }
    }

    public void printEven() {
    // print out values of even indices of the array
    InnerEvenIterator iterator = this.new InnerEvenIterator();
    while (iterator.hasNext()) {
    System.out.println(iterator.getNext() + " ");
    }
    }

    // inner class implements the Iterator pattern
    private class InnerEvenIterator {
    // start stepping through the array from the beginning
    private int next = 0;

    public boolean hasNext() {
    // check if a current element is the last in the array
    return (next <= SIZE - 1);
    }

    public int getNext() {
    // record a value of an even index of the array
    int retValue = arrayOfInts[next];
    //get the next even element
    next += 2;
    return retValue;
    }
    }

    public static void main(String s[]) {
    // fill the array with integer values and print out only
    // values of even indices
    DataStructure ds = new DataStructure();
    ds.printEven();
    }
    }

    The output is:
    0 2 4 6 8 10 12 14
    I want to ask about the two emphasized rows:

    1) at the first bold row, why does it use at the this keyword? I tested the code without the this keyword and it worked very fine.
    2) at the second bold row, how does it refer to the arrayOfInts field directly without the this keyword? here the arrayOfInts field is a member of the DataStructure class and not of the innerEvenIterator class?

    I'll be thankful for the one who will solve me this concern!

    Thanks in advance!!

    atar.


  2. #2
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    939
    Thanks
    6
    Thanked 202 Times in 178 Posts

    Default Re: Nested classes.

    1) at the first bold row, why does it use at the this keyword? I tested the code without the this keyword and it worked very fine.
    As with "this" and variables it can be dropped if there is no confusion.

    int foo;
    void setFoo(int foo) {
        this.foo = foo;
    }

    If the argument variable were something different there would be no need for the "this". Likewise if there were no other InnerEvenIterator classes in the package, using "this" would be unnecessary.

    2) at the second bold row, how does it refer to the arrayOfInts field directly without the this keyword?
    Instances of the the outer (or enclosing) class provide the context for the inner ones they contain. This is quite clear in the case of iterators: they always have to be iterators of something. That something is the instance of the enclosing class. Methods of the inner class have access to this context: the fields and methods of the enclosing class.

    Did you try using "this"? My guess is that it would fail precisely because, as you say, arrayOfInts belongs to DataStructure and not to InnerEvenIterator. What you can add is the name of the class to which it is a field:

    int retValue = DataStructure.this.arrayOfInts[next];

    "DataStructure.this" is a way of referring directly to the enclosing structure. Some times it is needed because of a conflict of names between fields of the inner and enclosing classes.

    -----

    My opinion is that you shouldn't put unneeded "this" or "Whatever.this" in the code because it stops the reader and makes them ask themselves "so where and what is the other variable or class from which this is being distinguished?" Likewise I wouldn't start mangling variable names to avoid them - setFoo(int __foo_in_arg) etc. "this" and "Whatever.this" have their place and are useful in that place.
    Last edited by pbrockway2; April 25th, 2012 at 02:59 PM.

  3. #3
    Junior Member
    Join Date
    Apr 2012
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default Re: Nested classes.

    Hi there!!

    Firstly, thanks you very much about your detailed answer.

    Secondly, there are several things that I didn't understand in your words:

    1) you said:"Likewise if there were no other InnerEvenIterator classes in the package, using "this" would be unnecessary" - and I didn't understand how is it possible to have additional "innerEvenItreator" classes in one package, here two classes with the same name isn't allowed?!

    2) you said: "Instances of the the outer (or enclosing) class provide the context for the inner ones they contain. This is quite clear in the case of iterators: they always have to be iterators of something. That something is the instance of the enclosing class. Methods of the inner class have access to this context: the fields and methods of the enclosing class." - I didn't understand why does the enclosing class provide the context for the inner one that it contain? here inside the code block of the inner class, the context provider should be the inner class as with a method of class, that inside the method's code block, the context provider is the method itself rather than the class that this method is a member of?!

    Again, thanks you about your great support. I hope you'll answer me on my new questions!

    Thanks in advance!!

    Atar.

  4. #4
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    939
    Thanks
    6
    Thanked 202 Times in 178 Posts

    Default Re: Nested classes.

    1) you said:"Likewise if there were no other InnerEvenIterator classes in the package, using "this" would be unnecessary" - and I didn't understand how is it possible to have additional "innerEvenItreator" classes in one package, here two classes with the same name isn't allowed?!
    I can't see any reason why there shouldn't be multiple classes: the full name of a type includes the packages and enclosing classes.

    For instance the following compiles just fine:

        /*File Foo.java*/
    public class Foo {
        class Bar {}
    }
     
     
        /*File: Bar.java*/
    public class Bar {}

    The compiled code includes three class files: Foo.class, Bar.class and Foo$Bar.class. Notice how the name of the enclosing class (Foo) is used to keep the names of the two Bar classES distinct. And notice how the name used for the inner class (Foo$Bar) is not a valid identifier within the Java language, so we have no choice but to use a circumlocution like "new this.Bar()" if we want to create one.

    I didn't understand why does the enclosing class provide the context for the inner one that it contain?
    I'm not sure I understand your second point.

    Your original question asked how a field of the enclosing class can be accessed without using the "this" keyword. In some sense there is no "how" or "why" to this: it just can. The field in question is within scope, and it can be accessed. Describing such variables as part of the context of an inner class instance was just a way of (trying to) make such access seem reasonable.

  5. #5
    Junior Member
    Join Date
    Apr 2012
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Red face Re: Nested classes.

    Hi there!!

    Thank you about your detailed response!!

    1) Of course, it is clear that two classes with the same name can be exist in two separated packages/files. In my previous question I meant to ask how does two classes with the same name can be exist in the same level of package. For instance, the following class structure will fail in compile time:

    /* file Foo.java */

    Public class Foo{
    Public class Bar{}

    Public class Bar{}
    }

    2) related to the second point, suppose I create the following class structure:

    Public class outerClass{

    public int myInt = 1;

    public class innerClass{

    public int myInt = 2;

    }

    }

    How can I distinguish between the outer "myInt" variable with the "1" value to the inner "myInt" variable with the "2" value? I ask that because using the "this" keyword to access to the outer "myInt" variable result to a compile time error.

    Thanks you very much!!

    Atar.

  6. #6
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    939
    Thanks
    6
    Thanked 202 Times in 178 Posts

    Default Re: Nested classes.

    1) Yes, you can't have two nested Bar classes. But you *can* have two Bar classes one nested, one not in the same package with the compiler doing a little name mangling to keep things straight. It is in this latter case that I was suggesting that the "this" in "new this.Bar()" would be required.

    2) I don't have a compiler on my phone but I imagine you would access the inner variable with "this.myInt" or just "myInt" and the outer one as "OuterClass.this.myInt".

  7. The Following User Says Thank You to pbrockway2 For This Useful Post:

    atar (April 29th, 2012)

  8. #7
    Junior Member
    Join Date
    Apr 2012
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Default Re: Nested classes.

    Hi there!!

    Thanks you very much about your kind support!!

    related to your words in the "2)" section, I succeed to access the outer variable by using "OuterClass.this.myInt", but to the inner identical variable (with the same name), the JRE throwed an exception when I try to access it. do you have any idea how to solve this problem?

    Thanks in advance!!

    atar.

  9. #8
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    939
    Thanks
    6
    Thanked 202 Times in 178 Posts

    Default Re: Nested classes.

    What is the code? What was the exception?

    (If the code is long remove anything that is not essential to illustrating the problem).

    The following accesses and prints the values fine:

    public class Outer {
        int var = 42;
     
        class Inner {
            int var = 666;
     
                /** Accesses both inner and outer variables. */
            void test() {
                System.out.println("inner var is " + var);
                System.out.println("outer var is " + Outer.this.var);
            }
        }
     
        public static void main(String[] args) {
            new Outer().new Inner().test();
        }
    }

  10. #9
    Junior Member
    Join Date
    Apr 2012
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Lightbulb Re: Nested classes.

    Hi there!!

    Thanks you very much about your kind response!

    The code that caused to the exception is exactly the code in my opening post, except that I added an identical "arrayOfInts" array in the inner (innerEvenIterator) class:

    // inner class implements the Iterator pattern
     private class InnerEvenIterator {
     // start stepping through the array from the beginning
     private int next = 0;
    private int[] arrayOfInts = new int[10];


    I'll be glad if you will guide me through the problem that caused the exception.

    Thanks in advance!!

    atar.

  11. #10
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    939
    Thanks
    6
    Thanked 202 Times in 178 Posts

    Default Re: Nested classes.

    Please say what the exception is. It is a good idea to post the entire stack trace because this also says on what line of your code the exception occurred.

    -----

    Once you have added that line of code the iterator will use the inner int array, not that of the outer data structure. Notice that the inner array is smaller which may be causing a problem. But this is guesswork: you ought to post the full runtime stack trace.

  12. The Following User Says Thank You to pbrockway2 For This Useful Post:

    atar (May 2nd, 2012)

  13. #11
    Junior Member
    Join Date
    Apr 2012
    Posts
    15
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Question Re: Nested classes.

    Hi there!!

    Thanks you again about your really kind support!

    Here is the full runtime stack trace, as you requested:

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
    at DataStructure$InnerEvenIterator.getNext(DataStruct ure.java:34)
    at DataStructure.printEven(DataStructure.java:17)
    at DataStructure.main(DataStructure.java:45)
    By the way, your guess is correct! once I changed the inner "arrayOfInts" variable to contain 15 elements, no exception was threw, but the big question is why??

  14. #12
    Super Moderator pbrockway2's Avatar
    Join Date
    Jan 2012
    Posts
    939
    Thanks
    6
    Thanked 202 Times in 178 Posts

    Default Re: Nested classes.

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
    at DataStructure$InnerEvenIterator.getNext(DataStruct ure.java:34)
    at DataStructure.printEven(DataStructure.java:17)
    at DataStructure.main(DataStructure.java:45)
    You read these stack traces from the top down, paying special attention to the first line that mentions your code because this is where the exception occurred.

    Line 34 of DataStructure.java is this one:

    public int getNext() {
        // record a value of an even index of the array
        int retValue = arrayOfInts[next];  // <----------------------- line 34
        //get the next even element
        next += 2;
        return retValue;
    }

    The stack trace is even more helpful because it says what the problem is: an array index is out of bounds. Specifically the value of next is either negative or greater than or equal to the length of the arrayOfInts. The next step in tracking down what is happening is to use System.out.println() to actually print the values of the index and the length:


    public int getNext() {
        System.out.println("At getNext() next=" + next + ", arrayOfInts.length=" + arrayOfInts.length);
            // record a value of an even index of the array
        int retValue = arrayOfInts[next];
            //get the next even element
        next += 2;
        return retValue;
    }

    Perhaps this will shed light on the big question of why the length of the inner array matters.

Similar Threads

  1. [SOLVED] Help with nested if statements.
    By joon in forum What's Wrong With My Code?
    Replies: 8
    Last Post: June 17th, 2011, 10:25 AM
  2. Help with Nested Loops
    By Plural in forum What's Wrong With My Code?
    Replies: 3
    Last Post: October 23rd, 2010, 03:31 PM
  3. Nested If Else Statement
    By jwill22 in forum What's Wrong With My Code?
    Replies: 6
    Last Post: October 6th, 2010, 02:46 PM
  4. nested loop
    By b109 in forum Java Theory & Questions
    Replies: 1
    Last Post: May 30th, 2010, 10:05 AM
  5. Nested try blocks
    By Ahmed. in forum Member Introductions
    Replies: 2
    Last Post: April 30th, 2010, 08:12 AM

Tags for this Thread