• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

Inner Classes

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I am learning about Inner Classes and have encountered a compilation error that I am having trouble figuring out.

I have created a class called Invoice (which is the outer, enclosing class) and within this, I have added an inner class called InvoiceItem:





I have created another class called UseInvoice, which creates two objects. One object is an instance of the Invoice class and the other is an instance of the InvoiceItem class.



The Invoice class compiles without any problem, however when trying to compile the UseInvoice class, I get the following error:

C:\Documents and Settings\JGehlot\Desktop\Java Videos\Java Files\Inner_Classes>javac UseInvoice.java
UseInvoice.java:3: package Invoice does not exist
import Invoice.*;
^
UseInvoice.java:16: cannot find symbol
symbol : class InvoiceItem
location: class UseInvoice
InvoiceItem myInvItem = myInvoice.new InvoiceItem(1,345, "Toy Train", 2) ;
^
2 errors

C:\Documents and Settings\JGehlot\Desktop\Java Videos\Java Files\Inner_Classes>


Note: UseInvoice.class and Invoice.class and Invoice$InvoiceItem.class are in the same folder (C:\Documents and Settings\JGehlot\Desktop\Java Videos\Java Files\Inner_Classes).


Could someone tell me what I am doing wrong? I think its something to do with the use of the import Invoice.*; statement at the top of the UseInvoice file.

Thanks

 
Rancher
Posts: 618
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Import is used for packages. Invoice is a class. You can use static import as a shortut to get to static members of a class but not inner classes. I updated your code so that it compiles. I also reformatted it and used code tags to make it easier to read. When you use code tags (see UseCodeTags) you will probably get more (better?) responses on this site.
 
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
welcome to the Ranch
 
Marshal
Posts: 80282
432
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You cannot import a class which does not have a package name.
 
Jay Gehlot
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thankyou Tom for your reply to my first post on this site.

Apologies for not using CodeTags, you are right, it would have made the code a lot easier to read and digest.

I've changed the code as you have suggested, in order to instantiate an object for the inner class and this works fine!

Actually the reason I initially did this is because I have been watching CBTNugget videos for the SCJP exam. The videos are actually quite old (created in 2004) for Java 1.4. The videos actually show this (import Invoice.*; code) and the code compiling, which was why I was a little confused as to why this wasn't working on my machine, using Java 1.6.

Maybe this was possible in Java 1.4??

Anyhow thankyou Tom and also thankyou Campbell.
 
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This particular thing has not changed between 1.4 and 1.6, or, in fact, 1.0. Import is used for packages, which have periods between each package level. You are using an inner class, which can be referred to as Outer.Inner and therefore possibly be confused with packages.

The capital letter on Invoice makes it suspect immediately; the language has no restriction on the use of capital letters in package names, but there is a strong convention of leading capitals used for class names, not package names at any level.

You could have had:

import one.two.three.Invoice;

followed by code; Invoice in this case is a class name, at the end of its package.

rc
 
Jay Gehlot
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So Ralph, I think I understand what you are saying. Invoice is the class and I am incorrectly trying to import the class, which is obviously not permitted.

I have two class files within the folder C:\Documents and Settings\JGehlot\Desktop\Java Videos\Java Files\Inner_Classes

The first class is Invoice and the second class (which holds main, and call Invoice) is UseInvoice.

Would you suggest to have write the following in the UseInvoice class:

import Inner_Classes.Invoice;
or
import "Documents and Settings\JGehlot\Desktop\Java Videos\Java Files\Inner_Classes";

I haven't yet gone through the chapter on packages, so I am still trying to find my way here.

Cheers

Jay
 
Ralph Cook
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Almost.

A class is what you do import. If your class Invoice is in a package called billing, with billing in a package called business, you could say:

import business.billing.Invoice;

This would enable you to use Invoice in your class without having to write business.billing.Invoice everywhere. The latter is called, incidentally, a "fully-qualified name" for the class, the former a "classname".

With packages, you can tell the compiler to import all the classes in a specific package:

import business.billing.*;

would allow you to use any class within the package business.billing without having to use the fully-qualified name of that class.

As far as I know, there is no way to import an inner class using "*"; you must enter the inner classname qualified with its outer classname any time you need the classname. I *think* you could import InvoiceItem by itself:

import business.billing.Invoice.InvoiceItem;

But I am not sure and haven't tried it. I am fairly sure you cannot import all inner classes of Invoice using the "*".

Now, as to your files: I cannot tell from your description whether Invoice and UseInvoice are in packages or not. The fact that they are in directories does not tell me that they are in classes. The fact that the directory has an underscore and capital letters suggests that it is not a package name; if it is, it does not follow the widely-used convention I mentioned about packages having names in lower case letters.

Look in the source. If they do not have a "package" statement at the top (it's required to be before any other statements), then they aren't in packages, and don't need to be imported at all. Your code can just say something like:

Invoice currentInvoice = new Invoice();

with no import statement and that will fine. Invoice is a fully-qualified name if Invoice is not in any package.

rc
 
what if we put solar panels on top of the semi truck trailer? That could power this tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic