• 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
  • Paul Clapham
  • Ron McLeod
  • paul wheaton
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Liutauras Vilda
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Piet Souris
Bartenders:
  • salvin francis
  • Mikalai Zaikin
  • Himai Minh

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: 16145
269
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.
 
Marshal
Posts: 26524
81
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: 332
42
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: 72619
317
  • 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.
 
Jj Roberts
Bartender
Posts: 332
42
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: 72619
317
  • 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: 12878
279
  • 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: 12878
279
  • 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: 72619
317
  • 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: 12878
279
  • 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.
 
When you have exhausted all possibilities, remember this: you haven't - Edison. Tiny ad:
ScroogeXHTML - a fast and small RTF to HTML5 and XHTML converter library
https://coderanch.com/t/742149/ScroogeXHTML-RTF-HTML-XHTML-converter
reply
    Bookmark Topic Watch Topic
  • New Topic