0

Forgive me if this has an answer somewhere; I didn't really know what to search for... Also, my terminology may be off (declare, instantiate, etc) as I am still learning Java and OOP.

I was reading the textbook: Data Structures and Abstractions, 3rd Ed by Frank Carrano (Chaper 20: Dictionary Implementation), and I came across a pretty standard looking class containing a private inner class. But there is something about the methodology I don't quite get.

I am having a difficult time understanding why you would declare an object (or array of objects) as a field in the outer class, then in the constructor, instantiate a temp object and initialize the field as the temp object rather than just instantiating the attribute itself in the constructor.

EDIT: I added the type parameter back into the code... K & V are used for key and value in this case since we are working with dictionaries. I don't know if that is important to the question or not...

I have rewritten the code in question here, renaming classes and such so they aren't so localized:

public class OuterClass<K, V> implements SomeInterface<K, V>
{
     private InnerClass<K, V>[] foo;                  // Declare array of inner class object
     private final static int CAPACITY = 10;    // Initial Array Capacity

     // Outer Class Constructor
     public OuterClass()
     {
          InnerClass<K, V>[] tempFoo = (InnerClass<K, V>[])new InnerClass[CAPACITY];
          foo = tempFoo;
     }

     // ...

     private class InnerClass<S, T>
     {
          // Inner Class Constructor
          private InnerClass()
          {
               // ...
          }

          // ...
     }
}

As mentioned, I tried to get rid of any specific details in the code, as I don't think they are relevant to the question. Is there any reason why you wouldn't just do this in the outer class constructor:

foo = (InnerClass[])new InnerClass[CAPACITY];

instead of:

InnerClass[] tempFoo = (InnerClass[])new InnerClass[CAPACITY];
foo = tempFoo;
Kurt E. Clothier
  • 276
  • 1
  • 11

3 Answers3

5

This is enough:

foo = new InnerClass[CAPACITY];

UPDATE after generics edit of OP:

With generic type parameters the situation changes because you use a raw type on the right side. In this case casting is necessary, and you get a compiler warning because the cast cannot be type-safe. So we then have:

foo = (InnerClass<K, V>[]) new InnerClass[CAPACITY];
Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
  • That's what I thought. Also, the casting is present in the book, which is why I put it here, although it is probably more implementation detail that could have been left out. – Kurt E. Clothier Apr 08 '14 at 20:01
  • @KurtE.Clothier Casting is completely unnecessary because the types of assignment left and right are exactly the same. – Meno Hochschild Apr 08 '14 at 20:03
  • @KurtE.Clothier You are right, type parameters are important to give you a proper answer, see my edit. – Meno Hochschild Apr 08 '14 at 20:12
  • Yet with or without type params, the temp local variable is as useless. – Marko Topolnik Apr 08 '14 at 20:13
  • Right, I know the type parameters and casting were related ( I don't know why I left out one but not the other) but I didn't think either had anything to do with the temp variable. – Kurt E. Clothier Apr 08 '14 at 20:15
  • And indeed it doesn't. The cast you have was just a distraction from the main point of your question, and that point doesn't at all depend on the existence of type parameters. – Marko Topolnik Apr 08 '14 at 20:16
3

There's no purpose for it in the code you posted. However there often can be a use-case for using this general method, if instantiation of the object might throw an Exception and you want to handle it. Consider something like this:

private final Image image;

public MyClass() {
    image = ImageIO.read(new File("myImage.png"));
}

This results in a compiler error because I haven't dealt with the possible IOException. So I have to do something like below, meaning I need the intermediary variable:

public MyClass {
    Image image = null;
    try {
        image = ImageIO.read(new File("myImage.png"));
    }
    catch(IOException ioe) {
        //Perform logging, whatever
    }
    this.image = image;
}

... So, just because it's meaningless for the code you pasted, don't think there's never a use for such a technique. Of course, this is only really the case for final variables.

asteri
  • 11,402
  • 13
  • 60
  • 84
-1

Yep, as Meno said. It doesn't make any sense.

james_dean
  • 1,477
  • 6
  • 26
  • 37