• 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
  • Ron McLeod
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Rob Spoor
  • Junilu Lacar
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Piet Souris
  • Carey Brown
Bartenders:

Understanding the laws of package access

 
Ranch Hand
Posts: 86
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
On pages 219 - 220 in the book 'Certified Associate Java SE 8 Programmer I' by Jeanne Boyarsky and Scott Selikoff, there is a code sample that challenges you to determine what will and will not compile based on package access:




All of the errors are in School.java:

Line 7: "The field Classroom.globalKey is not visible". Since when is a field with default access not visible to another package? default != private, right?

Line 8: "The constructor Classroom(int, String) is not visible". Even though the roomNumber field has a private access modifier, and the teacherName field has a protected access modifier, we are still importing everything from the my.school package on line 2, so why is visibility still an issue? Or do import statements only make the classes themselves visible, and not necessarily the variables inside of them?
 
Sheriff
Posts: 17405
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
default is also called package-private access which means it is visible only from the same package. It's not visible from outside the package.
 
Sheriff
Posts: 27527
88
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sam Peterson wrote:Or do import statements only make the classes themselves visible, and not necessarily the variables inside of them?



No, import statements have nothing at all to do with visibility. The purpose of an import statement to save the programmer from having to type fully qualified names all the time. For example in your second class there, if you didn't have the import statement then line 8 would have to be

 
Bartender
Posts: 387
47
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One of the tutorials in The Java™ Tutorials is on access modifiers. Reading through it might help clear up your understanding of the different levels of access. It can be found here.

In that tutorial there is a handy table for reference. It shows what has access to a certain member of a class with the different access modifiers:

Access Levels ModifierClass PackageSubclassWorld
publicYYYY
protectedYYYN
no modifierYYNN
privateYNNN
 
Marshal
Posts: 77157
370
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That table is slightly inaccurate about protected access. There are some circumstances when a protected class member/constructor is invisible in a subclass.
 
Jesse Duncan
Bartender
Posts: 387
47
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:That table is slightly inaccurate about protected access. There are some circumstances when a protected class member/constructor is invisible in a subclass.


Which circumstances are you referring to? It is true that the protected members of a class are only available to its subclasses in another package by inheritance only.
 
Campbell Ritchie
Marshal
Posts: 77157
370
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The gory details are all in the JLS (=Java® Language specification). It says that a protected member or constructor is accessible in code responsible for the implementation of the object. So an instance method or constructor or instance field declaration (I think) can use that protected member or constructor, but a static method can't. Nor can other classes in a different package access a protected member or constructor in a class inhering it from a superclass in a different package. There are more restrictions; see the JLS link.

It may be bad practice to use a protected member or constructor method in a constructor.

[edit]Strike out some text and add “method”.
 
Saloon Keeper
Posts: 14680
330
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A derived class D can only access a protected member of a base class B from a different package if it's done through an object reference with formal type D or a subclass of D:

The formal type of the local variable b is Base, and since Base is not Derived or a subclass of Derived, Derived is not allowed to access the protected members of Base through b.

What could be the reason for this seemingly ridiculous rule? Well, imagine that you had a type MyCollection with a protected field size, and you were implementing classes MyList and MySet that extend MyCollection. You wouldn't want to be able to access the size field of a MyList from a MySet, because those classes really don't have any business being all up in each other's internals. If MyList could access protected field size through a reference of type MyCollection, it could inadvertently be modifying a MySet object.
 
Stephan van Hulst
Saloon Keeper
Posts: 14680
330
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:So an instance method or constructor or instance field declaration (I think) can use that protected member or constructor, but a static method can't.


This is incorrect. You can access protected members just fine from static methods, as long as you're doing it through a reference with the proper formal type.

It may be bad practice to use a protected method in a constructor.


This doesn't really have anything to do with the method being protected, as much as it has to do with the method being overridable. It's fine to call a protected final method from a constructor.
 
Campbell Ritchie
Marshal
Posts: 77157
370
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for the correction, which was obvious in your earlier example. About calling methods, I was just trying to warn people against calling methods left right and centre from constructors....and didn't do it very well.
 
Stephan van Hulst
Saloon Keeper
Posts: 14680
330
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree it's good to be cautious. A good rule of thumb is to only call private methods from constructors.
reply
    Bookmark Topic Watch Topic
  • New Topic