Forum Stats

  • 3,759,882 Users
  • 2,251,610 Discussions
  • 7,870,857 Comments

Discussions

Access modifiers ignored !?!

843798
843798 Member Posts: 24,864
edited Jun 25, 2001 3:03PM in Java Runtime Environment (JRE)
Hi

please, have a look at the code below and let me know your opinions

// ------------- source file 1 ------------------------
package pckg1;

public class Dog {

final public static void main (String[] args) {

pckg2.Puppy puppy = new pckg2.Puppy("Spot");
System.out.println(puppy.getName());

}
}

// ------------- source file 2 --------------------
package pckg2;

class Puppy {

String name;

public Puppy(String name) {
this.name = name;
}

String getName() {return name;}

}

Each class belongs to a different package. Obviously if you compile Puppy first and attempt compiling Dog the compiler will complain about several things (class Puppy not being public, method getName() not being public, etc...).

Now,
if you change the Puppy class so that the necessary bits are public, re-compile Puppy and then Dog it will work.
When you subsequently go back to Puppy and remove the added public access modifiers and re-compile JUST the Puppy class and try running Dog IT WILL STILL WORK AS IF EVERYTHING IN THE PUPPY CLASS WERE PUBLIC.

I don't thing this is right. If the access modifiers cannot be relied on then the whole system is flawed.

PS: Running on W2K, the behaviour observed on JRE 1.2.2_007, 1.3.0_02 as well as on 1.4.0-beta-b65.

Cheers

Ales Krestan

Comments

  • 843798
    843798 Member Posts: 24,864
    Access modifiers are checked at compile time. Obviously,
    your JVM is not doing runtime checks (which is probably
    the right thing in most instances).

    What you have done is made a change to your source
    code and not done a complete enough recompile to
    build the system with the new code base. Your
    development tools/process should prevent this from
    happening.

    Runtime checks for such things would be a huge cost
    to pay to ensure that you cannot do what you have
    done.
  • 843798
    843798 Member Posts: 24,864
    Thanks for the response, but I hold different views on the matter. Although performance surely is of a great importance, it should not come at the expense of consistency.

    A few more thoughts on the same:

    1/ my understanding is that it is responsibility of the class loader to decide what to do in such cases during the resolution case. Apparently the application class loader of SUN's JVM ignores it and so does the extension class loader of the same JVM.
    2/ surprisingly (or rather expectedly) when attempting to load both classes (with the dodged version of Puppy) using the system class loader the JVM throws java.lang.IllegalAccessError.
    3) the same trick cannot be done with an interface. If you try to dodge an interface using the same principle and try to load it using the application class loader JVM will refuse to run (or load) the class that uses the dodged interface.
    4/ the class loader DOES other things, so why not to check the access modifiers as well. It should check if the class can be instantiated, for example. See the section 2.17.3 Linking: Verification, Preparation, and Resolution of the JVM specification.


This discussion has been closed.