Get method from Class then invoke via Object - java

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.

Related

Why are there no subclasses of java.lang.Class?

java.lang.Class defines multiple methods which only apply to a certain type of class, e.g.:
getComponentType: Only relevant for arrays
getEnumConstants: Only relevant for enums
So why is there, for example, no ArrayClass which defines the getComponentType method instead?
This appears to be more or less a design choice. Since i did not design this language, i cannot answer it with certainty, but i'll try to explain potential reasons for this.
So why is there for example no ArrayClass which defines the getComponentType method instead?
The trick to understanding this is, that the java.lang.Class class is not a direct equivalent to the class you are coding. This specific class is only used to represent the created class at runtime (for example: for the use of reflections).
As from the Java-Doc of the Class (here from Java 7):
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
You are writing custom classes, if you write your code, which means that your created code is the class. If you create a class called the ArrayClass, this is your class. The java.lang.Class class is then only usable at runtime to analyze the class of this specific Object.
For the design in Java, two more layers of complication are added.
First: You can analyze every object, which is a subtype of java.lang.Object. The method getClass is defined here. This means that you are able to introspect any object for any specific detail. If the specific type of the Object is not an enum for example, the class returns null upon calling getEnumConstants. If you had specific sub-types of the java.lang.Class, you would have to cast the instance before introspecting it, which would make it more annoying to work with.
Second: The java.lang.Class object, representing your type is created lazy, within the ClassLoader. Upon referenzing a specific type, the ClassLoader checks whether or not the Class is already loaded and if not, loads it. It then creates the java.lang.Class-Objects, which represents this specific Type. This class-object can then be used, to create instances of your type.
If the java language had different subtypes for the java.lang.Class, the ClassLoader would have to instantiate the correct subtype of the Class, corresponding to what would be needed. If you where able to create custom subtypes of the java.lang.Class, this would get out of hand quickly. How is the ClassLoader supposed to know which Class-instance is connected to your Type? Would you have to write specific Class-instances and somehow mark your created type to use that Class-instance? You could imagine something like this:
public class MyType extends ... implements ... type MyClassInstance
But then, how do you fill up custom fields within your custom java.lang.Class instance? Those complications may be the reason, that the java.lang.Class has a generic type, representing the connected Type. Event though there are a million possible solutions to those complications, there still might be an argument to be made for usability and robustness.
As Oracle point out in there Design Goals of the Java Programming Language:
The system that emerged to meet these needs is simple, so it can be easily programmed by most developers; familiar, so that current developers can easily learn the Java programming language; ...
As much as one would love to see something like this within the language, this feature would make it way more complicated, since it would allow developers to change the behavior of the newInstance method for example. You could introduce an Exception within this Method and one might think, the constructor threw an Exception, even though it did not. This goes into the same (or a similar) direction as Why doesn't Java offer operator overloading?, with that, you are essentially overriding the new keyword.
The Class currently is final (likely because it is a core language construct). This prohibits subtypes of java.lang.Class. If the class should receive subtypes, it has to loose final which means anyone could override any specific detail for a class. Calling getClass could result in any unknown type, that could do anything.
With that, we now only have specific subtypes of classes, we still cannot access them. To do this, we have to do one of the following:
Either add a generic type to the Object like this (i don't want to start a debate about super or extends, this is just an example):
public class Object<T extends Class> {
public final native T getClass();
}
This is required because we want to have certain classes connected to certain objects. With this however, we are not specifying how to instantiate the class. Normally a class is instantiated through the ClassLoader. Again from the JavaDoc:
Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.
This would no longer be viable, except we require certain aspects like a private constructor. Also, we had to provide every custom Class as native C++ code.
The other possibility would be, to define the getClass method in implementations something like this (this code has different generic based issues, but again, just an example):
public class Object {
public <T extends Class<?>> T getClass() {...}
}
public class MyType {
public MyClass getClass() { return new MyClass(); }
}
Which would open the door to more complicated issues introduced earlier. You could now do work in here, that you are not supposed to do. Imagine a InvocationHandler for example. The other issue with this is that now the developer has the freedom to decide whether or not a Class is instantiated only once or multiple times, which would break for example the Class-Based-Programming and of course some aspects of the Java-Language.
Even though i cannot answer with certainty, i hope this helped a bit.

Java inheritance, two-step inheritance

I have the main abstract class that is a base for bunch of classes. Some of them does not need all the fields and methods from the main abstract class, so I have created second abstract class and splitted main abstract class into two parts. The main abstract class contains, for example, a, x fields and their getters/setters, the second abstract class inherits from the main and contains additional b, c fields and their getter/setters. There are simple classes that are inheriting from the main class,and more complicated are inheriting from the second class. I want to create objects of each class as instances of the main class. Is it right way to do that? I have to type check and cast when I want to use methods from the second abstract class. It makes my code complicated. How can I solve this problem?
MainAbstractClass ---> SecondAbstractClass ---> MyComplicatedClasses
|
|
V
MySimpleClasses
One of the OO principles is Favor composition over inheritance.
This means that common behavior is not provided through base classes but via Component classes which are passed in via dependency injection (preferably as constructor parameters.
The answer depends on your actual needs.
You can instead choose to store the extended abstract class specific fields in a class that does not implement your base class and make it a member of more complicated classes.
You can choose to keep everything in a single base class and nothing forces you to use all the fields of an interface in every class that implemented your interface.
You can also keep using your approach but since you store the classes as an instance of the base class, it will be hard to read.
I believe that if you think code does not look very good, it is probably not good. However, there is usually no single answer to this kind of design questions and the best solution is relative to your preferences.
I think this need of type cast is a smell of fragile design. Here when we assume MyComplicatedClass ISA KIND OF MainAbstractClass as shown by TJ Crowder then object must behave as MainAbstractClass (meaning it can honor only API of MainAbstractClass). If it expects special treatment as MyComplicatedClass its false commitment and will need Casting. Such casting (by identifying type) goes against OO principles and kills polymorphism. Later this will end up in Ladder of InstanceOf and type casts as in the scenarios rightly pointed out by T.J. Crowder.
I would suggest readdress the design. e.g. though our all user defined type instances ARE KIND OF Object, but we use Object API only for methods defined in Object class. We do not use Object o = new MyClass(). There are occasions in frameworks or like Object.equals() method where type cast is needed as API is defined before even concrete extension is written. But it is not a good idea for such simple complete (without open hooks for extensions) Hierarchies.

Is it mandatory utility class should be final and private constructor?

By making private constructor, we can avoid instantiating class from anywhere outside. and by making class final, no other class can extend it. Why is it necessary for Util class to have private constructor and final class ?
This is not a mandate from a functional point of view or java complication or runtime. However, it's a coding standard accepted by the wider community. Even most static code review tools, like checkstyle, check that such classes have this convention followed.
Why this convention is followed is already explained in other answers and even OP covered that, but I'd like to explain it a little further.
Mostly utility classes are a collection of methods/functions which are independent of an object instance. Those are kind of like aggregate functions as they depend only on parameters for return values and are not associated with class variables of the utility class. So, these functions/methods are mostly kept static. As a result, utility classes are, ideally, classes with only static methods. Therefore, any programmer calling these methods doesn't need to instantiate the class. However, some robo-coders (maybe with less experience or interest) will tend to create the object as they believe they need to before calling its method. To avoid that, we have 3 options:
Keep educating people to not instantiate it. (No sane person can keep doing it.)
Mark the utility class as abstract: Now robo-coders will not create the object. However, reviewers and the wider java community will argue that marking the class as abstract means you want someone to extend it. So, this is also not a good option.
Private constructor: Not protected because it'll allow a child class to instantiate the object.
Now, if someone wants to add a new method for some functionality to the utility class, they don't need to extend it: they can add a new method as each method is independent and has no chance of breaking other functionalities. So, no need to override it. Also, you are not going to instantiate it, so no need to subclass it. Better to mark it final.
In summary, instantiating a utility class (new MyUtilityClass()) does not make sense. Hence the constructors should be private. And you never want to override or extend it, so mark it final.
It's not necessary, but it is convenient. A utility class is just a namespace holder of related functions and is not meant to be instantiated or subclassed. So preventing instantiation and extension sends a correct message to the user of the class.
There is an important distinction between the Java Language, and the Java Runtime.
When the java class is compiled to bytecode, there is no concept of access restriction, public, package, protected, private are equivalent. It is always possible via reflection or bytecode manipulation to invoke the private constructor, so the jvm cannot rely on that ability.
final on the other hand, is something that persists through to the bytecode, and the guarantees it provides can be used by javac to generate more efficient bytecode, and by the jvm to generate more efficient machine instructions.
Most of the optimisations this enabled are no longer relevant, as the jvm now applies the same optimisations to all classes that are monomorphic at runtime—and these were always the most important.
By default this kind of class normally is used to aggregate functions who do different this, in that case we didn't need to create a new object

State of Object, which don't has any attribute

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.

Is there a rule of thumb for when to code a static method vs an instance method?

I'm learning Java (and OOP) and although it might irrelevant for where I'm at right now, I was wondering if SO could share some common pitfalls or good design practices.
One important thing to remember is that static methods cannot be overridden by a subclass. References to a static method in your code essentially tie it to that implementation. When using instance methods, behavior can be varied based on the type of the instance. You can take advantage of polymorphism. Static methods are more suited to utilitarian types of operations where the behavior is set in stone. Things like base 64 encoding or calculating a checksum for instance.
I don't think any of the answers get to the heart of the OO reason of when to choose one or the other. Sure, use an instance method when you need to deal with instance members, but you could make all of your members public and then code a static method that takes in an instance of the class as an argument. Hello C.
You need to think about the messages the object you are designing responds to. Those will always be your instance methods. If you think about your objects this way, you'll almost never have static methods. Static members are ok in certain circumstances.
Notable exceptions that come to mind are the Factory Method and Singleton (use sparingly) patterns. Exercise caution when you are tempted to write a "helper" class, for from there, it is a slippery slope into procedural programming.
If the implementation of a method can be expressed completely in terms of the public interface (without downcasting) of your class, then it may be a good candidate for a static "utility" method. This allows you to maintain a minimal interface while still providing the convenience methods that clients of the code may use a lot. As Scott Meyers explains, this approach encourages encapsulation by minimizing the amount of code impacted by a change to the internal implementation of a class. Here's another interesting article by Herb Sutter picking apart std::basic_string deciding what methods should be members and what shouldn't.
In a language like Java or C++, I'll admit that the static methods make the code less elegant so there's still a tradeoff. In C#, extension methods can give you the best of both worlds.
If the operation will need to be overridden by a sub-class for some reason, then of course it must be an instance method in which case you'll need to think about all the factors that go into designing a class for inheritance.
My rule of thumb is: if the method performs anything related to a specific instance of a class, regardless of whether it needs to use class instance variables. If you can consider a situation where you might need to use a certain method without necessarily referring to an instance of the class, then the method should definitely be static (class). If this method also happens to need to make use of instance variables in certain cases, then it is probably best to create a separate instance method that calls the static method and passes the instance variables. Performance-wise I believe there is negligible difference (at least in .NET, though I would imagine it would be very similar for Java).
If you keep state ( a value ) of an object and the method is used to access, or modify the state then you should use an instance method.
Even if the method does not alter the state ( an utility function ) I would recommend you to use an instance method. Mostly because this way you can have a subclass that perform a different action.
For the rest you could use an static method.
:)
This thread looks relevant: Method can be made static, but should it? The difference's between C# and Java won't impact its relevance (I think).
Your default choice should be an instance method.
If it uses an instance variable it must be an instance method.
If not, it's up to you, but if you find yourself with a lot of static methods and/or static non-final variables, you probably want to extract all the static stuff into a new class instance. (A bunch of static methods and members is a singleton, but a really annoying one, having a real singleton object would be better--a regular object that there happens to be one of, the best!).
Basically, the rule of thumb is if it uses any data specific to the object, instance. So Math.max is static but BigInteger.bitCount() is instance. It obviously gets more complicated as your domain model does, and there are border-line cases, but the general idea is simple.
I would use an instance method by default. The advantage is that behavior can be overridden in a subclass or if you are coding against interfaces, an alternative implementation of the collaborator can be used. This is really useful for flexibility in testing code.
Static references are baked into your implementation and can't change. I find static useful for short utility methods. If the contents of your static method are very large, you may want to think about breaking responsibility into one or more separate objects and letting those collaborate with the client code as object instances.
IMHO, if you can make it a static method (without having to change it structure) then make it a static method. It is faster, and simpler.
If you know you will want to override the method, I suggest you write a unit test where you actually do this and so it is no longer appropriate to make it static. If that sounds like too much hard work, then don't make it an instance method.
Generally, You shouldn't add functionality as soon as you imagine a use one day (that way madness lies), you should only add functionality you know you actually need.
For a longer explanation...
http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It
http://c2.com/xp/YouArentGonnaNeedIt.html
the issue with static methods is that you are breaking one of the core Object Oriented principles as you are coupled to an implementation. You want to support the open close principle and have your class implement an interface that describes the dependency (in a behavioral abstract sense) and then have your classes depend on that innterface. Much easier to extend after that point going forward . ..
My static methods are always one of the following:
Private "helper" methods that evaluate a formula useful only to that class.
Factory methods (Foo.getInstance() etc.)
In a "utility" class that is final, has a private constructor and contains nothing other than public static methods (e.g. com.google.common.collect.Maps)
I will not make a method static just because it does not refer to any instance variables.

Categories

Resources