The way I understand it, Java object model is 3 levels, each level describes the level beneath it, therefore there is one Meta class shared by all Classes (which are themselves objects?).
My question is - how are constructors implemented in Java? (or any other class methods) my logic says that constructors should appear in the Meta classes, but since there is only one Meta class, it doesn't make any sense that it keeps all possible constructors, or is my understanding of this is all wrong..
In Java there's a single metaclass: the instances of the class Class are used to represent the types of classes and interfaces. The constructors are defined at the class level, not at the metaclass level.
Your question targets nothing special about constructors: From the point of describing classes on a metalevel there is the same concept for constructors, "normal methods" and fields.
So think of it this way:
Each class in Java is described by a certain set of informations:
Name of the class
the superclass
the implemented interfaces
a list of constructors and their signatures
a list of (static and non-static) methods and their signatures
a list of (static and non-static) fields and their types
For your convenience this information is available to you during runtime - this is the "reflection API".
Since the same type of information is available for each class loaded by the JVM, this is bundled in a own class named java.lang.Class.
So one instance of the class Class describes the class java.lang.String, another instance of Class describes my.own.class.Foo.
java.lang.Class itself is of course also a class - therefore there also exists an instance of Class describing the class Class. And I think that's where things get recursive somehow.
Summary: There is only one metaclass: java.lang.Class. Multiple instances (meta-instance?) of the metaclass describe individual classes - including the metaclass itself. Constructor descriptions are part of the instances of the metaclass.
Related
As Java 9 is going to allow us to define private and private static methods too in interfaces, what would be the remaining difference in interface and class?
Moreover, is Java moving towards multiple inheritance slowly?
Private interface methods in Java 9 behave exactly like other private methods: They must have a body (even in abstract classes) and can neither be called nor overridden by subclasses. As such they do not really interact with inheritance. Talking of which (and particularly multiple inheritance), there are (at least?) three kinds of it:
Inheritance of types means that one type can be another type, e.g. String is an Object. Java allowed multiple inheritance of types from day one (via interfaces).
Inheritance of behavior means that one type can inherit the behavior of another type. Before Java 8, only classes could implement methods, so there was only single inheritance of this kind. With Java 8 came default methods, which allowed interfaces to implement methods, thus giving Java multiple inheritance of behavior.
Inheritance of state means that a type inherits another type's internal state (i.e. fields). As it stands (Java 9 and everything currently proposed for future Java versions), only classes can have state, so there is only single inheritance of this kind.
As you can see private interface methods do not add anything here.
Regarding your question of how interfaces and classes compare, there are two main differences: multiple inheritance and state. Interfaces support the former, classes can have the latter. Since state is kind-of important in typical OOP, classes will remain relevant. 😉
If there were a way for an interface to force an implementation to have a particular non-public field or straight-out define one itself, the game would change and interfaces could compete with classes.
Private methods are not inherited by subclasses, so this feature doesn't affect implementation classes. I believe the private methods in interfaces allow us to share code between default methods.
Java interfaces still cannot have non-static members. That's a big difference and not multiple inheritance IMO.
Java 9 interfaces still cannot contain fields and constructors. This makes a huge difference between classes and interfaces, so Java 9 is far from multiple inheritance.
Java Interface in version 9 have private methods but static private. The feature has been introduced to allow modular methods. One function should work with one responsibility instead of using lengthy default methods. It has nothing to do with multiple Inheritance. The more private static methods, the more you will be able to write the clean and reusable code. Anyways, static methods whether public or protected can not be overridden.
Although its an old question let me give my input on it as well :)
abstract class: Inside abstract class we can declare instance
variables, which are required to the child class
Interface: Inside interface every variables is always public static
and final we cannot declare instance variables
abstract class: Abstract class can talk about state of object
Interface: Interface can never talk about state of object
abstract class: Inside Abstract class we can declare constructors
Interface: Inside interface we cannot declare constructors as purpose of
constructors is to initialize instance variables. So what
is the need of constructor there if we cannot have instance
variables in interfaces.
abstract class: Inside abstract class we can declare instance and static blocks
Interface: Interfaces cannot have instance and static blocks.
abstract class: Abstract class cannot refer lambda expression
Interfaces: Interfaces with single abstract method can refer lambda expression
abstract class: Inside abstract class we can override OBJECT CLASS methods
Interfaces: We cannot override OBJECT CLASS methods inside interfaces.
I will end on the note that:
Default method concepts/static method concepts in interface came just to save implementation classes but not to provide meaningful useful implementation. Default methods/static methods are kind of dummy implementation, "if you want you can use them or you can override them (in case of default methods) in implementation class" Thus saving us from implementing new methods in implementation classes whenever new methods in interfaces are added. Therefore interfaces can never be equal to abstract classes.
This question already has answers here:
When to use inner classes in Java for helper classes
(10 answers)
Closed 8 years ago.
So I have a ClassA:
public ClassA {
String key;
List<ClassB> value;
}
And this ClassA is mapped to a database table (with 2 columns having key -> list of values) and the values here get stored as a row in there.
public ClassB {
Integer data1;
...
String dataN;
/* constructors and some getters/setters follow */
}
To clarify, ClassB just contains some data that is being stored in database.
When ClassA is being saved, List<ClassB> is being converted to JSON string and getting saved.
There are 2 ways to define ClassB.
Either have it as a regular class
Define it as a inner class(not sure if static or not) inside classA.
ClassB is currently not being used anywhere else in the project.
What do you think should be the right way and why?
I am bit confused regarding nested classes and I cannot distinguish if they are being misused or not.
Personally, if the class is small (for example just an helper) and is not to be used anywhere else, I would prefer doing an inner class. However, this is mostly a matter of opinion.
I think the best in these case is to make sure everyone in your dev team work the same way so it is easier for everyone to debug.
Note that there is a difference between inner class and nested class. A nested (static) class is an inner class declared static, while a simple inner class is normally not static.
Nested static class can be accessed anywhere using Class.NestedStaticClass.
See Nested class documentation for more details and example.
Here an interesting quote from the link I gave u before :
Serialization of inner classes, including local and anonymous classes,
is strongly discouraged. When the Java compiler compiles certain
constructs, such as inner classes, it creates synthetic constructs;
these are classes, methods, fields, and other constructs that do not
have a corresponding construct in the source code. Synthetic
constructs enable Java compilers to implement new Java language
features without changes to the JVM. However, synthetic constructs can
vary among different Java compiler implementations, which means that
.class files can vary among different implementations as well.
Consequently, you may have compatibility issues if you serialize an
inner class and then deserialize it with a different JRE
implementation. See the section Implicit and Synthetic Parameters in
the section Obtaining Names of Method Parameters for more information
about the synthetic constructs generated when an inner class is
compiled.
You might also consider using Anonymous inner class. An anonymous inner class is a class coded directly in the instanciation. For example
new ParentClassName(constructorArgs) {
members..
}
ClassB is currently not being used anywhere else in the project.
I think the key word here is "currently".
If you imagine a situation in which ClassB might be useful in other places in the project (say, if that project grows in a particular way, or if there are other tables that might map to the same structure in the future), then it should probably be a "normal" class.
If the class is logically tied to ClassA. For example, ClassA represents a train and ClassB train cars, which are always related to trains and never to other vehicles which are not trains, then you should define it as a nested class or inner class of ClassA.
Whether to make it nested or inner depends on the type of connection between an object of class ClassB and one of ClassA. It's not always a clear-cut issue, but remember that static nested classes can exist independently of their parent class. (e.g. you can manufacture a train car before you ever create a train object that it will be part of, and you can move train cars between trains), while inner classes always contain an invisible reference to their parent object, and such an object has to exist before you can create an object of the inner class.
All else being equal, I think I would gamble on a static nested class as an initial solution. If I realize that there are other places that need the same class, it's going to be relatively easy to refactor it.
Why can I not have a interface inside of a inner class? Why are they inherently static? Sorry if it's a stupid question, I've tried my best to google this again and again but I can't seem to wrap it around my head. As in why cannot I declare these in inner classes/local classes?
Also just as a confirmation, the reason we can have static final variables in a interface is because they do not specify the state or any of that sort of the implementation right? If we lose static and use just a final, we need a instance which makes no sense cause you can't instantiate a interface. Sorry, I really am confused, and I know I should just make another question but I think these two questions are somewhat related.
Think about what static means - "not related to a particular instance". So, as you point out, a static field of class Foo is a field that does not belong to any Foo instance, but rather belongs to the Foo class itself.
Now think about what an interface is - it's a contract, a list of methods that classes which implement it promise to provide. Another way of thinking about this is that an interface is a set of methods that is "not related to a particular class" - any class can implement it, as long as it provides those methods.
So, if an interface is not related to any particular class, clearly one could not be related to an instance of a class - right?
*Note, as #Owlstead points out, there are ways of defining interfaces within classes. But, for the purposes of wrapping your head around what an interface is (which seems to be what you're working on), I would ignore those possibilities for now as they distract from and possibly obscure the purpose of interfaces in general.
Why are they [interfaces] inherently static?
The difference between a static and a non-static nested class is in whether their instances have implicit references to enclosing instances (of the containing class), as well as to local variables from the containing scope. Before Java 8, there was no way for an interface to make use of such implicit references, because an interface could not initialize any non-static fields or provide any method implementations. (It still can't initialize non-static fields, though now it can provide default method implementations.) So before Java 8, there was no meaning in a non-static nested interface.
Also, from an implementation standpoint, these implicit references are implemented as an extra fields on the inner class, and they also require extra arguments to the inner-class constructor (in order to initialize these fields). Interfaces don't have fields, or constructors, so there's no way to implement this.
(Note: I don't usually recommend trying to understand language design decisions in terms of the implementation, because a single language feature can have many different correct implementations. But I think this is one case where understanding the implementation helps to understand the specification, hence the previous paragraph.)
Why can I not have a interface inside of a inner class?
Because interfaces are implicitly static: JLS §8.5.1:
A member interface is implicitly static (§9.1.1). It is permitted for the declaration of a member interface to redundantly specify the static modifier.
and you can't have non-final statics in an inner class.
Why are they implicitly static?
Because that's the way they designed it.
why cannot I declare these in inner classes/local classes?
Because they're implicitly static.
the reason we can have static final variables in a interface is because they do not specify the state or any of that sort of the implementation right?
Right.
If we lose static and use just a final, we need a instance
Right.
which makes no sense cause you can't instantiate a interface.
Yes you can. You can instantiate a class which implements the interface, or you can instantiate a method-local anonymous implementation of it. The real issue here is multiple inheritance of interfaces.
You cannot have an interface inside of an inner class because an inner class only exists within the context of an instance of an 'outer class'. Since this is the case, your interface would be de facto non-static.
You can, however have an interface inside of a nested class. See #owlstead answer. By placing the 'static' keyword on a the declaration of an 'inner class', it becomes a first class citizen, referencable from outside the outer class and (mostly) independent of the context of the outer class. Nested classes can be instantiated outside of the outer class; inner classes cannot.
After Java 16 release we can have static members inside Inner classes and static variables can be declared if they are final or effectively final. See this image
https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-8FD2B5E3-46C7-4C6C-8E8A-64AB49ABF855
I am coming from Java to Objective C, and the idea of a class object has me wondering about similarities with Java. From the Objective C guide in Apple documentation:
A class definition's information is compiled and recorded in data structures made available to the runtime systems. The compiler creates just one object, a class object, to represent the class.
So my understanding is that the class object is created for all classes that are going to be used by the program, and a class object is what is used to create objects for that class.
For comparison, does the JVM have a similar object for all classes it loads?
Given that Java was derived directly from Objective-C (no, really, it was), the runtime models of the two are quite similar.
In Java, the notion of a "Class" isn't quite as generic as it is in Objective-C.
In Objective-C, a Class is an instance of what is known as the metaclass. For all intents and purposes, each Class object in Objective-C does exactly as you say; it describes a particular class available in the Objective-C runtime.
The same is conceptually true of Java classes. There is one key difference. In Objective-C, class methods are inherited across subclasses and more significantly a subclass can override a superclass's class method(s).
For example, the NSArray class implements the +array class method (the '+' means "class method"). The NSMutableArray subclass of NSArray overrides +array to return a mutable instance instead.
java.lang.Class is more akin to the Objective-C runtime API; it is the mechanism via which you introspect the classes available in the runtime. Since Java doesn't have functional API, the API is wrapped up in an appropriately named class. java.lang.Class is kinda the runtime API and the metaclass all in one.
A comparable structure in Java would be java.lang.Class.
I think there is a class object for each class.
That class object is the one that, at low level, is used for functions as class_getName(), class_getSuperclass(), class_getVersion(), class_respondsToSelector(). If there would be a single class object for all the classes, then those functions would return the same result for all the classes.
I have a large tree-like data structure of objects which behave mostly identical but differ in one or two methods that calculate some keys used to navigate through the structure. The divergent behaviour depends on where the objects are in the structure.
I was starting out with an abstract base class and have several subclasses that implement each type of behaviour. This gives me around ten subtypes which are a) hard to name intelligently and b) look a little unwieldy in my project's source folder, both because they are so similar.
I would prefer having a single factory class that doles out instances of anonymous subclasses on the fly. This would give me a lot of flexibility and open the door for a lot of nice improvements, such as sharing data and parametrizing stuff and would look a lot cleaner in my code structure. However, the whole thing is very sensitive to memory footprint and memory access time, and I'd have lots of these objects. Do I have to consider any disadvantages or pecularities of anonymous classes?
Like non-static inner classes, anonymous classes have a hidden reference to the class they're defined in, which can cause problems if you use serialization and of course prevent objects of the outer class from being eligible for GC - but that's unlikely to be a problem if you do it in a single factory class.
Anonymous classes are not different than named classes.
But yes, having many objects can impact your memory footprint, and performance (garbage-collection).
From what you tell, I wonder if it would be possible to split your class in two parts:
All the constant methods in one class (no subclass of this class).
All variable methods (see later) are encapsulated in a Position interface. You can have a few classes that implement it. The objects of these classes would have no state, so they can be shared instances which is excellent for performance and memory).
Variable methods : calculate some keys depending on the position in the structure.
As mentioned an anonymous inner class usually has a hidden reference to the class in which it is declared. However, you can eliminate this by declaring the anonymous class from inside a static method (simple, and not perfectly obvious).
The major disadvantage to this technique is that the classnames seen in jars will be numbered (like "MyClass$0.class") and not easily identifiable in stacktraces (except of course by using the line numbers) and without toString() methods not easily identifiable in your own println statements.
Declaring static inner classes is a great technique. It will eliminate all these disadvantages and keep your file hierarchy compact. Also consider making these inner classes private or final unless you need to extend them.
A class is a class. It doesn't matter whether it's a "top-level" classes, a regular inner class, a local inner class, or an anonymous inner class.
Non-static inner classes, or inner classes that access private members of their enclosing class will have a tiny bit of extra code in them. To non-static inner classes, the compiler adds a member variable that references the enclosing instance. If an inner class accesses any private members of the enclosing class, the compiler will synthesize an accessor in the enclosing class with "package-private" (default) accessibility.