How can a JVM decide if a class “belongs” (e.g. inner or nested classes) to another class? - 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.

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?

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.

Related

Is it better to implement two classes or one class in the following case?

I have a class "Vertex" with 4 attributes and a class "Vertex_" with one attribute. The one attribute in Vertex_ is also in Vertex. Is it a good design to keep the two classes or is it better to program just the class Vertex, although there will be 3 variables, which are not used, when I instantiate an object which needs just the one attribute?
Class Vertex_ is actually somewhat a duplicate of Class Vertex.
I would suggest using inheritance and having Class Vertex inherit the attribute from the parent Class Vertex_ while having the 3 other attributes Class Vertex_ does not have.
TL;DR
This is a question that deserves a very long answer.There are two reasons for inheritance and the reason for doing it can depend on the language being used. One reason is for code reuse. Without knowing anything else about your situation, it would seem you are inheriting simply to reuse an attribute (but I suspect there could be more you will be reusing). But, there are other ways of getting code reuse without inheritance, for example containment, which is often a better way.
A powerful feature of object-oriented programming is the ability to substitute one type of object for another. When a message is sent to that object, the correct method implementation is invoked according the actual type of object receiving the message. This is one type of polymorphism. But in some languages the ability to substitute one object for another is constrained. In Java I can only substitute an instance of class B for an instance of class A if B is a descendant of A. So inheritance becomes important in Java to support polymorphism.
But what does it mean to be able to substitute a B instance for an A instance? Will it work? Class A has established a contract stating what each of its methods requires before you can successfully call it and at the same time states what each method promises to deliver. Will the methods of class B live up to that contract? If not, you really cannot substitute a B for an A and expect the program to run correctly. B may be a subclass of A but it is not a subtype of A (see Liskov substitution principle]).
In a language such as Python, inheritance is not required for polymorphism and coders are more apt to use it as code-reuse mechanism. Nevertheless, some people feel that subclassing should only be used to express subtyping. So, if Vertex_ is only using one of the four attributes it has inherited, I am doubtful that an instance of Vertex_ could be safely substituted for an instance of Vertex. I would not do the inheritance unless the language were C++ and then I would use private inheritance.

What is the difference between ::class and ::class.java in Kotlin?

In Java, we write .class (for example: String.class) to get information about the given class. In Kotlin you can write ::class or ::class.java. What is the difference between them?
By using ::class, you get an instance of KClass. It is Kotlin Reflection API, that can handle Kotlin features like properties, data classes, etc.
By using ::class.java, you get an instance of Class. It is Java Reflection API, that interops with any Java reflection code, but can't work with some Kotlin features.
First you need to understand about Reflection. According to the docs:
Reflection is a set of language and library features that allows for introspecting the structure of your own program at runtime.
In simple words, it gives you the ability to get the code you have written i.e., the class name you have defined, the function name you have defined, etc. Everything you have written, you can access all these at runtime using Reflection.
::class and ::class.java are basic features of Reflection.
::class gives you a KClass<T> reference and ::class.java gives you Class<T> reference.
Example,
val a = MyClass::class
can be interpreted as
val a = KClass<MyClass>()
Note: Above code is not syntactically correct, because KClass is an interface and interfaces cannot be instantiated. It is just to give you an idea.
A Class<T> class gives you information about the metadata of the T class like interfaces it is implementing, its functions' names, its package name, etc.
KClass is similar to Class but it gives information about some more properties(Kotlin related properties) than Class. All the information a KClass<T> reference can give you about the T class are listed here https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/#properties
According to the Kotlin documentation, when we create an object using any class type as below the reference type will be type of KClass.
val c = MyClass::class // reference type of KClass
Kotlin class reference is not the same as a Java class reference. To get a Java class reference, use the .java property on a KClass instance.
val c = MyClass::class.java // reference type of Class Java

How are Classes an Annotations Related in Java?

I found this quote
the first step to using reflection is to obtain a Class object that
represents the class whose annotations you want to obtain
from Herbert Schildt
Can anyone explain that sentence and also "Class" with respect to annotations. Does an annotation reside inside a "Class" or not?
You can add annotations to lots of symbols like classes, methods, constructors etc.
The point of the quote is, that in order to access those annotations at run-time, your entry point is the class object. From there you can start inspecting it, looking for methods, members etc. and access their annotations. This API is also called reflection, because it essentially reflects the code you have written as an object at run-time (including annotations).

When should I use a regular class in Scala?

It seems to me that I can make just about anything using object, trait, abstract class and in rare occasions, case class. Most of this is in the form object extends trait. So, I'm wondering, when should I, if ever, use a plain, standard class?
This is not a right place to ask this question
Looks like you are new Scala
Class is a specification for something(some entity) you want to model . It contains behavior and state
There is only one way to declare so called regular class using keyword class
Both trait and abstract class are used for inheritance.
trait is used for inheritance (generally to put common behavior in there). trait is akin to interface in Java. multiple inheritance possible with traits but not abstract class.
A class can extends one class or abstract class but can mixin any number of traits. Traits can have behavior and state.
case class is a nothing but a class but compiler produces some boilerplate code for us to make things easy and look good.
object is used when you want to declare some class but you want to have single instance of the class in the JVM (remember singleton pattern).
If an object performs stateful computations on its members i.e. its members are declared with vars;
Or, even if its member are only declared with vals but those vals store mutable data structures which can be edited in place, then it should be an ordinary (mutable) class akin to a Java mutable object.
The idiomatic way of using Case classes in Scala is as immutable types i.e. all the constructor arguments are vals. We could use vars but then we lose the advantages of case classes like equality comparisons will break over time.
Some advise from Programming in Scala by Odersky et al on deciding between using traits, abstract classes and concrete classes:
If the behavior will not be reused, then make it a concrete class. It is not reusable behavior after all.
If it might be reused in multiple, unrelated classes, make it a trait.
Only traits can be mixed into different parts of the class hierarchy.
If you want to inherit from it in Java code, use an abstract class.
Since traits with code do not have a close Java analog, it tends to be
awkward to inherit from a trait in a Java class. Inheriting from a
Scala class, meanwhile, is exactly like inheriting from a Java class.
As one exception, a Scala trait with only abstract members translates
directly to a Java interface, so you should feel free to define such
traits even if you expect Java code to inherit from it. See Chapter 29
for more information on working with Java and Scala together.
If you plan to distribute it in compiled form, and you expect outside
groups to write classes inheriting from it, you might lean towards
using an abstract class. The issue is that when a trait gains or loses
a member, any classes that inherit from it must be recompiled, even if
they have not changed. If outside clients will only call into the
behavior, instead of inheriting from it, then using a trait is fine.
If efficiency is very important, lean towards using a class. Most Java
runtimes make a virtual method invocation of a class member a faster
operation than an interface method invocation. Traits get compiled to
interfaces and therefore may pay a slight performance overhead.
However, you should make this choice only if you know that the trait
in question constitutes a performance bottleneck and have evidence
that using a class instead actually solves the problem.
If you still do not know, after considering the above, then start by
making it as a trait. You can always
change it later, and in general using a trait keeps more options open.

In Scala, plural object name for a container of public static methods?

I've written a Scala trait, named Cache[A,B], to provide a caching API. The Cache has the following methods, asyncGet(), asyncPut(), asyncPutIfAbsent(), asyncRemove().
I'm going to have a few static methods, such as getOrElseUpdate(key: A)(op: => B). I don't want methods like this as abstract defs in the Cache trait because I don't want each Cache implementation to have to provide an implementation for it, when it can be written once using the async*() methods.
In looking at Google Guava and parts of the Java library, they place public static functions in a class that is the plural of the interface name, so "Caches" would be the name I would use.
I like this naming scheme actually, even though I could use a Cache companion object. In looking at much of my code, many of my companion objects contain private val's or def's, so users of my API then need to look through the companion object to see what they can use from there, or anything for that matter.
By having a object named "Caches" is consistent with Java and also makes it clear that there's only public functions in there. I'm leaning towards using "object Caches" instead of "object Cache".
So what do people think?
Scala's traits are not just a different name for Java's interfaces. They may have concrete (implemented) members, both values (val and var) and methods. So if there's a unified / generalized / shared implementation of a method, it can be placed in a trait and need not be replicated or factored into a separate class.
I think the mistake starts with "going to have a few static methods". Why have static methods? If you explain why you need static methods, it will help figure out what the design should be.