Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a JVM decide if a class “belongs” (e.g. inner or nested classes) to another class?

I want to understand class files and inner/nested classes a bit better and I'm wondering about the following things:

  • Is the InnerClasses attribute used to refer tothe inner/nested classes in the ´containing´ class or is it used in the inner/nested classes to refer to the ‘container’ class?
  • Is the InnerClasses attribute in class files sufficient? E.g. Do inner/nested classes have to follow the name mangling with $ or is this just a convention?
  • Is there a way to make a class look like an inner/nested class to the JVM without setting the InnerClasses attribute and does this depend on the JLM vendor? (I remember hearing that IBM's implementation had less strict requirements in some parts.)
  • How much does the class loading mechanism of the JVM interact with Java reflection? Would it be possible to make the JVM disagree with the results from Java reflection?

I tried looking it up in the JVM specification but didn't find a description of the actual mechanism.

I only found this sentence in “The InnerClasses Attribute” remotely connected to my question:

The Java virtual machine does not currently check the consistency of the InnerClasses attribute with any class file actually representing a class or interface referenced by the attribute.

like image 353
soc Avatar asked Nov 10 '11 15:11

soc


People also ask

How do you define an inner class or nested class?

A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.

How do you know if a class is inner class?

To check whether the class is a local inner class, java. lang. Class provides a method called isLocalClass(). This method returns true if the given class is a local class and false otherwise.

What is difference between nested and inner class in Java?

In Java programming, nested and inner classes often go hand in hand. A class that is defined within another class is called a nested class. An inner class, on the other hand, is a non-static type, a particular specimen of a nested class.


2 Answers

A few additions to the previous answer:

Is the InnerClasses attribute used to store the contained inner/nested classes in the containing class or is it used in the inner/nested classes to refer to the ‘container’ class?

The bytecode of every compiled class is stored in a separate .class file. The the actual "inner classes" are not stored in that attribute. As the previous post pointed out, that attribute only points to classes that the compiler knew about when creating the bytecode.

Is the InnerClasses attribute in class files sufficient? E.g. Do inner/nested classes have to follow the name mangling with $ or is this just a convention?

Is there a way to make a class look like an inner/nested class to the JVM without setting the InnerClasses attribute and does this depend on the JLM vendor? (I remember hearing that IBM's implementation had less strict requirements in some parts.)

For both questions, I am not certain. But I think the concept of inner/nested classes is something that the Java language (and hence the Java compiler provides). In the bytecode, there should not be any difference between a class that was declared as a normal public class and some nested or inner class. You could easily try out how an given VM handles this like so:

  • Create a class with some nested and inner classes
  • Write a little program that tries to load and instantiate one of the inner classes through reflection from outside the scope of defining class. You must use reflection here, because the Java compiler will not allow you to instantiate a nested class that is not in scope! If you can successfully instantiate the class, that is evidence that internally the VM does not handle nested and normal classes differently.

How much does the class loading mechanism of the JVM interact with Java reflection? Would it be possible to make the JVM disagree with the results from Java reflection?

I don't understand this last question. Could you explain a bit more what you mean when you say the VM and reflection should disagree?

like image 195
Jochen Avatar answered Nov 15 '22 09:11

Jochen


I know that there is an inner class attribute in class files, but is this sufficient?

The InnerClasses attribute is in the byte code and it lists all the known inner classes of the outer class. This is not something you can use directly.

E.g. Do inner/nested classes have to follow the name mangling with $ or is this just a convention?

The compiler will follow this convention and you have no control over it.

Is there a way to make a class look like an inner/nested class to the JVM without setting the inner class attribute and does this depend on the JLM vendor? (I remember hearing that IBM's implementation had less strict requirements in some parts.)

You can create a class with the same name. YOu cna try that for yourself.

How much does the class loading mechanism of the JVM interact with Java reflection?

I don't believe the class loader uses reflection. However reflection may get its information from the same place the class loader does. I don't see why it would matter.

Would it be possible to make the JVM disagree with the results from Java reflection?

You can use reflection to corrupt the data in reflection based objects. Again, not sure why you would want to do this.

like image 26
Peter Lawrey Avatar answered Nov 15 '22 09:11

Peter Lawrey