We all know state of an Object is value of it's attributes (instance variables), but if class doesn't has any attribute (no inherited attributes), what would be the state of an Object of such class.
There is a word for such objects - stateless.
There is no such thing as a Java class without a parent class. The default parent would be used, e.g. java.lang.Object.
At a minimum every instance of a class has two attributes: a reference address and a Class type. Note, not every class can be instantiated. There is also some space used in the ClassLoader and any String(s) may (or may not) be interned. This actual implementation might vary slightly on the specific version of the JDK and run-time platform, and additional optimizations can be added by the JIT. However, as a Java developer you are not responsible for this memory management and I would be wary of premature optimization.
first thing
any class we write in java will extend Object class by default if there is no extends written by the developer.
so each and every class will definitely have a parent with no doubt atleast Object class.
second
if you dont put any attributes in your class , obviously it will get all the instance variables except private gets inherited to your class.
so it will have atleast object state but it will not serve any purpose
An object with no data members and links to other objects is a stateless object and in this form can hardly be of any use.
This kind of classes can nevertheless be usefull, because of its methods. It can be...
a base for a further inheritance. It declares/defines some methods, that could be inherited by derived classes. This class will probably be an abstract class, having no objects at all (although not a condition)
a service class. It can define some methods, which in nature do not belong to concrete objects but are used by other objects. Like some all-purpose mathematical operations, a service that returns a current time or similar. These methods can be static, so again no instances are needed.
We call those object stateless. As the name suggests, they have no state.
Referring to other answers/comments, even though every Java object implicitly extends Object, mind that Object has no fields. So even though every object has a runtime address and class attributes, for all practical purposes you can still consider some objects stateless.
Next, it is definitely not true that stateless objects serve no purpose! You can use stateless object for:
1) Grouping functions with similar functionality, similar to java.lang.Math, which groups mathematical functions.
2) Passing functionality as a parameter, e.g. Comparator<T> can be used to sort objects that do not implement Comparable<T>, and it definitely needs no state.
Stateless objects are somehow similar to immutable objects: their state can never be changed and therefore they are always thread-safe.
You may also want to see JEE Stateless Session Beans which differentiate between a converstional state and an instance state.
Related
Consider the following:
Map<Class<?>, Object> myMap = new HashMap<Class<?>, Object>();
Foo fooObject = New Foo();
myMap.put(fooObject.getClass(), fooObject)
Notice that java.lang.Class does not implement the hashCode() method itself, but inherits it from java.lang.Object implicitly. I verified this in JDK 1.8.
Is java.lang.Class safe to use as a key for a java.util.HashMap?
Will myMap.get(Foo.class) always return the values which I put like myMap.put(fooObject.getClass(), fooObject)? Consider the software to have various classloaders and serialization mechanisms. Will it still be the same result? If not... What would be an alternative?
Off the top of my head, would there be any reason to just not use the string class names? E.g. instead use:
myMap.put("Foo", fooObject);
If you are paranoid that maybe there could be more than one Foo class in scope, you could use the full canonical name:
myMap.put(Foo.class.getCanonicalName(), fooObject);
Is java.lang.Class safe to use as a key for a java.util.HashMap?
Yes.
Will myMap.get(Foo.class) always return the values which I put like myMap.put(fooObject.getClass(), fooObject)?
Yes.
Using a Class object as a key in a HashMap is safe. The Class class inherits the Object::equals and Object::hashCode methods. Thus equals for Class objects is testing object identity.
This is the correct semantics for type equality in Java. The implementation of the ClassLoader::defineClass method ensures that you can never get two different Class objects representing the same Java type.
However, there is a wrinkle. The Java Language specification (JLS 4.3.4) states this:
At run time, several reference types with the same binary name may be loaded simultaneously by different class loaders. These types may or may not represent the same type declaration. Even if two such types do represent the same type declaration, they are considered distinct.
(The binary name is related to the FQDN of a named type, and takes account of anonymous classes, and array types.)
What this means is that if you (successfully) call ClassLoader::defineClass for classes with the same fully qualified name in two different classloaders, you will get different Java types. Irrespective of the bytecodes you used. Furthermore, if you attempt to cast from one type to the other one, you will get a class cast exception.
Now the question is does this matter in your use-case?
Answer: probably not.
Unless you (or your framework) are doing tricky things with classloaders, the situation does not arise.
If it does, then you probably need the two types (with the same FQDN and different classloaders) to have the different entries in the HashMap. (Because the types are different!)
But if you need the two types to have the same entry, then you can use the FQDN for the class as the key, which you can obtain using Class::getCanonicalName. If you need to cope with array classes, etc, then use Class::getName which returns the binary name for the type.
What about serialization mechanisms?
A Class object cannot be serialized using Object serialization, since Class does not implement Serializable. If you implement / use some other serialization mechanism that does support the serialization of Class objects, then that mechanism needs to be compatible with JLS 4.3.4.
Instances of Class are unique per ClassLoader so it is not needed to override hashCode or equals.
There is a difference between run-time and compile-time type. It is possible to simultaneously load multiple classes of the same fully-qualified class name, if (and only if) they are loaded by different class loaders. Then such classes are distinct run-time types, and cannot be cast to one another, even if they are identical.
Hence the answer to your question depends simply on which effect you consider desirable:
If you desire to treat those separately loaded and incompatible classes as distinct in your map, use Class as the key. There will never be more than one live instance of Class with the same name and loader, so the Class class correctly does not override the hashCode and equals methods. So it is fine to use it as a HashMap key, although IdentityHashMap will give the same behavior, probably more efficiently.
If you desire to distinguish classes based only on their name, regardless of how (or whether) they were loaded, then use their string name as the map key.
#talex I tested it like below and you seem to be right:
public class ClassUnique {
public static void main(String [] args) throws ClassNotFoundException {
Class<?> c1 = Class.forName("java.util.Date");
Class<?> c2 = Class.forName("java.util.Date");
System.out.println(c1.equals(c2));
}
}
Output is true
EDIT: #Maarten I think you are right. Especially if you are running within an application container like Websphere or Weblogic there might be multiple class loaders in play which could screw this up. So in the end the simplest correct solution would be to just use the Class instance itself.
I would consider using IdentityHashMap. It does not rely on equals.
This class is designed for use only in the rare cases wherein reference-equality semantics are required.
I was wondering whether Class instances are immutable. The declared methods names do not suggest that the instance state is changed when they are invoked, but I found no explicit guarantee on the javadoc.
Scenario: I need to store unique class names in a Set. Ideally, I would like to populate the set with Class instances to avoid unnecessary calls to Class.forName() when I need to access the classe via reflection. However, it preferable to use immutable objects as keys of sets. Hence I was wondering if I could use Class instances right away.
First, The generics part Class<?> really doesn't matter here. Sure, no raw types, so Class<?> is better than Class, but for your question, the wildcard doesn't matter.
So in essence, you are asking whether Class objects are immutable. And for all practical purposes, they are.
Class objects come into existence when a class loader loads a class, and they stay put unless the whole class loader is unloaded, and everything it loaded with it.
Which can't happen when such class objects are still used in a map somewhere.
On the other hand: Class.forName() shouldn't be too expensive for classes already loaded. And when things such as serialization come into play, people suggest to go with String instead of Class objects for example (see here).
One has to distinguish between the immutable identity of a class object, and the actual "code" belonging to the class. That code can be changed at runtime (by instrumentation, think hot swap of code). But the class name, and its each code, and equals() equality should not be affected by that. Because the "identity" stays the same.
Final note: as the interesting comments below lay out, there are certain ways to alter Class objects to a certain degree. But all of these activities are definitely "out of the norm". Therefore: theoretically, you might prefer Strings over Class objects, but practically, in "normal" applications, using Class should work fine, too.
As I don’t really agree with other answer I decided to write this one,
Classes are not immutable, but they are unique - only one instance of Class object can exist for one class.
BUT class it not defined by its name, as classes might be from different class loaders, and different class loaders might have classes with same names - but that will be different classes, you would get ClassCastException if you would pass some object between code handled by 2 different class loaders if that object type would exist in both of them (as separate one, not inherited).
Class instances can be still safely used in Set, as they use default implementation of hashset/equals so only same instances of Class will be considered equals.
But to decide if you should use String or Class you need to know how exactly your app is supposed to work, as like I said, multiple classes with same name can exist between different class loaders.
And by just storing class name you can’t be sure that Class.forName will return same instance as expected it might even load some other class with same name from current class loader instead of using expected one.
Is there a way where I can prevent the parent class to be serialized?
When we do a serialization of the subclass all the way up till the parent class the serialization is performed.
Can I restrict the serialization of the parent classes and serialize the only sub class I am working on?
It is possible. Just declare your class as implements Externalizable and write exactly what you need in the writeExternal() method, taking care not to serialize anything from the superclass, and read exactly that back in the readExternal() method.
Or, just implement Serializable and provide your own readObject()/writeObject() methods, again taking care not to serialize anything from the superclass, and in this case also not calling defaultWriteObject() or defaultReadObject().
In both cases the actual serialization of the current class's data is entirely up to you.
Whilst it is technically possible to fine tune each level of inheritance on its own - even to the extent of excluding super class fields - you might want to step back here.
Basically there are two cases:
The super class does not have any fields / state. Then you have nothing to exclude anyway.
The super class has state, represented by fields of that class.
So how do you think to meaningfully address the second part? You see when you allow deserialisation without the data for the super class fields - that means that you might have to do a lot of additional testing. To make sure that super class methods don't throw exceptions - because all of a sudden fields are null instead of being initialized.
In other words: it is possible that "leaving out" all these values - you are creating objects which behave completely different. Are you prepared for handling all the effects of that?
Meanung: skipping super class fields requires you to interfere with serialization code. It might require a lot of additional testing effort. And what do you gain? A few bytes less of data transfer at runtime.
Beyond that: what is the purpose of an inheretance hierarchy that has 4 levels - but where the super class state is irrelevant?
So my non-answer: carefully consider if your idea is really the best OO design to solve the underlying requirements.
In order to invoke a method on a object via reflection, the only way I know how to do it is like so:
Object o = ...;
Method m = o.getClass().getMethod("methodName",null);
Object x = m.invoke(o,null);
Why doesn't Java have a getMethods method in the Object class? (As well as getSuperClass, getFields, etc, etc).
So we could just do something like:
Object x = o.invoke("methodName",null);
Why not? I assume this is for performance reasons.
(Also as a side note. In English, it makes more sense to say 'subject invokes object', so that would be in programming terms, object invoke method. But with Java we get 'method invoke on object'. Glad I could confuse you today.)
I believe the reason is that java.lang.Object is supposed to serve as the root of the class hierarchy and any method on it should pertain to instances of that object rather than the concept of an object.
Adding reflection utility methods to Object would spoil this. You'd have a choice of calling o.myMethod() or o.invoke("myMethod", null) and this would introduce a style of programming in Java that is not compile-safe, in that there is no compile-time guarantee that "myMethod" exists in the latter. This would make it very easy for developers to do away with type safety and just use .invoke all the time without bothering to consider proper object-oriented design.
By forcing developers to explicitly ask for an instance of Class, we maintain this separation between the reflection API and "concrete" Java. So, while it can sometimes be a pain, it's good to encourage developers to code properly. Also, it means that the OOP concept of an object is represented by java.lang.Object and the concept of a class is represented by java.lang.Class, which is a nice, clear distinction of responsibility.
The class Object
is the root of the class hierarchy.
It describes behavior that every class will need.
Any additional behavior is described by the sub classes, but a sub class doesn't necessarily have to have behavior. You can declare a class of constants, an enum, or even an array. Then it wouldn't make sense to have an invoke method on those.
Why is that a variable used in an Interface is PUBLIC STATIC FINAL? Why "static" in particular?
A field declared in an interface can only be a constant anyway, so why would it depend on which instance you use to access it?
Putting fields in interfaces is often poor style anyway these days. The interface is meant to reflect the capabilities of classes that implement it - which is completely orthogonal to the idea of a constant. It's certainly a nasty idea to use an interface just to declare a bunch of constants. I do occasionally find it useful to make the interface type expose constants which are simple implementations - so a filtering interface might have "ALLOW_ALL" and "ALLOW_NONE" fields, for example.
I suppose you could conceive of a scenario where implementing an interface did actually add an instance field to your class - but that would break encapsulation not only in terms of it being implicitly public, but also by specifying part of the implementation instead of the API.
Because you can not instantiate an interface. Also there cannot be any method body to use a non-static non-final variable.
Why wouldn't it be static?
It's a constant associated with the interface, rather than with any particular instance of it.
The main reason I guess is implementation detail of the VM/language.
If an interface is not allowed to have non-static variables, there's no need to allocate memory for the interface during the creation of the class. There's also no need for special naming/renaming mechanisms in case you inherit variables with the same name. The only thing you need is some table to call the correct functions when the interface is used.
In short - it makes the live of the language / VM maintainer easier. If you really want to take a look at multiple inheritance and its pitfalls and traps, read Object Oriented Software Construction by Bertrand Meyer (2nd Edition). Then you understand why the interface needs to be so simple (and yet archives most of the things multiple inheritance does).
An interface is a contract that defines the interaction between objects.
This interaction is defined by the exposed methods, not by the variables. Variables would only describe the internal working, not the interaction.
Note that variables should never be used for interaction. According to the OOP principle of encapsulation, it would be a crime to let 1 class access a variable of another class directly.
Constants (e.g.Math.PI) are the only acceptable exception. Since constants are the only kind of variables that can be accessed directly by other classes without violating the principle of encapsulation, all variables in an interface are treated as public static final variables (i.e. constants)