Java Reflection - Methods Introspection - java

Method[] theMethods = myClass.getMethods();
for( Method m : theMethods ){
...
}
Will the array include all the methods of the class? public, private, protected and all inherited?
Will I have access to all of them mainly the private and protected ones?
If not, how can I get all the methods of a class and also have access to all?

The Javadoc makes this pretty clear:
Returns an array containing Method objects reflecting all the public member methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.
To get at non-public methods, use getDeclaredMethods.

To get all methods of a class you need to recursively call getDeclaredMethods() on the class and all it's superclasses. Depending on what you want to achive with it you might need to remove duplicates which can occur due to method overloading.

From the API doc:
Returns an array containing Method
objects reflecting all the public
member methods of the class or
interface represented by this Class
object, including those declared by
the class or interface and those
inherited from superclasses and
superinterfaces.
So it gets you only public methods. To get all methods, you have to use getDeclaredMethods() on the class and all its superclasses (via getSuperclass()).
In order to call non-public methods, you can use setAccessible(true) on the Method object (if the security manager allows it).

Related

Why doesn't java allow to assign weaker access privileges to static methods in a child class?

I understand why java doesn't allow to set weaker access privileges for overridden methods, but why is it the same for static methods? I mean, these methods only hide each others, right? So what's the problem from the encapsulation point of view?
P.S.
I know that there are 5 rules for hiding a method
The method in the child class must have the same signature as the method in the parent
class.
The method in the child class must be at least as accessible or more accessible than the
method in the parent class.
The method in the child class may not throw a checked exception that is new or
broader than the class of any exception thrown in the parent class method.
If the method returns a value, it must be the same or a subclass of the method in the
parent class, known as co-variant return types.
The method defined in the child class must be marked as static if it is marked as
static in the parent class (method hiding). Likewise, the method must not be marked
as static in the child class if it is not marked as static in the parent class (method
overriding).
But after all, I don't get the idea from the encapsulation prospective
The same rules are valid and for method hiding
https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.8.3
Static methods have special access permissions that allow friend access to members within a instance. For example, you could have a static method called create that creates a default instance of the class and directly modifies data within the instance without using instance properties or instance methods (just for a usage example, not necessarily a usage recommendation).
Because of this special access, lower access permissions to the static methods could allow you to create an object in a state that you could not otherwise use, or modify an object in an unpredictable and non-encapsulated way.
This is only a minor annoyance for most user-defined classes, but allowing this when sub-classing e.g. containers could expose serious undefined behavior problems.

Java : final constructor [duplicate]

Why can't constructors be final, static, or abstract in Java?
For instance, can you explain to me why this is not valid?
public class K {
abstract public K() {
// ...
}
}
When you set a method as final it means: "I don't want any class override it." But according to the Java Language Specification:
JLS 8.8 - "Constructor declarations are not members. They are never inherited and therefore are not subject to hiding or overriding."
When you set a method as abstract it means: "This method doesn't have a body and it should be implemented in a child class." But the constructor is called implicitly when the new keyword is used so it can't lack a body.
When you set a method as static it means: "This method belongs to the class, not a particular object." But the constructor is implicitly called to initialize an object, so there is no purpose in having a static constructor.
The question really is why you want constructor to be static or abstract or final.
Constructors aren't inherited so can't be overridden so whats the use
to have final constructor
Constructor is called automatically when an instance of the class is
created, it has access to instance fields of the class. What will be
the use of a static constructor.
Constructor can't be overridden so what will you do with an abstract
constructor.
A Java constructor is implicitly final, the static / non-static aspects of its semantics are implicit1, and it is meaningless for a Java constructor to be abstract.
This means that the final and static modifiers would be redundant, and the abstract keyword would have no meaning at all.
Naturally, the Java designers didn't see in any point in allowing redundant and/or meaningless access modifiers on constructors ... so these are not allowed by the Java grammar.
Aside: It is a shame that they didn't make the same design call for interface methods where the public and abstract modifiers are also redundant, but allowed anyway. Perhaps there is some (ancient) historical reason for this. But either way, it cannot be fixed without rendering (probably) millions of existing Java programs uncompilable.
1 - Actually, constructors have a mixture of static and non-static semantics. You can't "call" a constructor on an instance, and it they are not inherited, or overridable. This is similar to the way static methods work. On the other hand, the body of a constructor can refer to this, and call instance methods ... like an instance method. And then there is constructor chaining, which is unique to constructors. But the real point is that these semantics are fixed, and there is no point allowing a redundant and probably confusing static modifier.
public constructor: Objects can be created anywhere.
default constructor: Objects can be created only in the same package.
protected constructor: Objects can be created by classes outside the package only if it's a subclass.
private constructor: Object can only be created inside the class (e.g., when implementing a singleton).
The static, final and abstract keywords are not meaningful for a constructor because:
static members belong to a class, but the constructor is needed to create an object.
An abstract class is a partially implemented class, which contains abstract methods to be implemented in child class.
final restricts modification: variables become constant, methods can't be overridden, and classes can't be inherited.
Final: Because you can't overwrite/extend a constructor anyway. You can extend a class (to prevent that you make it final) or overwrite a method (to prevent that you make it final), but there is nothing like this for constructors.
Static: If you look at the execution a constructor is not static (it can access instance fields), if you look at the caller side it is (kind of) static (you call it without having an instance. Its hard to imagine a constructor being completely static or not static and without having a semantic separation between those two things it doesn't make sense to distinguish them with a modifier.
Abstract: Abstract makes only sense in the presence of overwriting/extension, so the same argument as for 'final' applies
No Constructors can NEVER be declared as final. Your compiler will always give an error of the type "modifier final not allowed"
Final, when applied to methods, means that the method cannot be overridden in a subclass.
Constructors are NOT ordinary methods. (different rules apply)
Additionally, Constructors are NEVER inherited. So there is NO SENSE in declaring it final.
Constructors are NOT ordinary methods. (different rules apply)
Additionally, Constructors are NEVER inherited. So there is NO SENSE in declaring it final.
No Constructors can NEVER be declared final. YOur compiler will always give an error of the type "modifer final not allowed"
Check the JLS Section 8.8.3 (The JLS & API docs should be some of your primary sources of information).
JLS section 8 mentions this.
Constructors (§8.8) are similar to methods, but cannot be invoked
directly by a method call; they are used to initialize new class
instances. Like methods, they may be overloaded (§8.8.8).
But constructors per say are not regular methods. They can't be compared as such.
why constructor can not be static and final are well defined in above answers.
Abstract: "Abstract" means no implementation . and it can only be implemented via inheritance. So when we extends some class, all of parent class members are inherited in sub-class(child class) except "Constructor". So, lets suppose, you some how manage to declare constructor "Abstract", than how can you give its implementation in sub class, when constructor does not get inherit in child-class?
that's why constructor can't be
abstract .
lets see first
final public K(){
*above the modifier final is restrict 'cause if it final then some situation where in some other class or same class only we will override it so thats not gonna happen here proximately not final
eg:
we want public void(int i,String name){
//this code not allowed
let static,, static itz all about class level but we create the object based constructor by using 'new' keyword so,,,,,, thatsall
abstract itz worst about here not at 'cause not have any abstract method or any declared method
Unfortunately in PHP the compiler does not raise any issue for both abstract and final constructor.
<?php
abstract class AbstractClass
{
public abstract function __construct();
}
class NormalClass
{
public final function __construct() {
echo "Final constructor in a normal class!";
}
}
In PHP static constructor is not allowed and will raise fatal exception.
Here in AbstractClass obviously a constructor either can be declared as abstract plus not implemented or it can be declared as something among (final, public, private, protected) plus a function body.
Some other related facts on PHP:
In PHP having multiple constructor __construct() is not possible.
In PHP a constructor __construct() can be declared as abstract, final, public, private and protected!
This code was tested and stood true for in PHP versions from 5.6 up to 7.4!

Using reflection - how to get all fields and methods

Using Java reflection:
How can I get all the methods of a given object (private, protected, public etc)
And perhaps create a structural representation of the class
And finally, serialize the object into String or byte array
Does this idea look sound? or this won't get me anywhere?
What I'm trying to achieve is to be able to:
Serialize any java.lang.Object into byte array or String
Class / Objects that don't implement Serializable will be thrown into my application for serialization
Sounds complicated. Just use XStream.
String xml = new XStream().toXML(whatever);
Question 1: How to get all methods of a class.
getDeclaredMethods will provide you with access to all of the methods on a class.
Returns an array of Method objects reflecting all the methods declared
by the class or interface represented by this Class object. This
includes public, protected, default (package) access, and private
methods, but excludes inherited methods.
Example: Method[] methods = Integer.class.getDeclaredMethods();
Question 2: Create a Structural Representation of a Class
I'm not sure why you would need to do this since it already exists. You can always retrieve an object's class, which provides you with its structure.
To get all methods and fields for a class, use getDeclaredMethods and getDeclaredFields. I'm not sure if you can use it to re-compose a non serializable class though, and I'm not sure I would either. But maybe you can find some ideas here: How to serialize a non-serializable in Java?
Class.getDeclaredMethods() and Class.getDeclaredFields() return methods and fields with any visibility declared in current class only. These methods do not return inherited stuff. To do this you have to iterate over the class hierarchy and call these methods for each super class, i.e.:
List<Method> methods = new ArrayList<>();
List<Field> fields = new ArrayList<>();
for (Class c = clazz; c != null; c = c.getSuperClass()) {
methods.add(c.getDeclaredMethods());
fields.add(c.getDeclaredFields());
}

Does the object of superclass created when object of derived class is created?

If I have a class C which inherits class B and class B inherits class A, then
If I create an object of Class C, is the object of superclasses created?? If yes, how??
How to access the private members of class A??
Does the object of superclass created when object of derived class is created?
No.
The superclass constructor is used to initialize the superclass-defined state of the currebt object, but this does NOT amount to creating an instance of the superclass.
If I have a class C which inherits class B and class B inherits class A, then If I create an object of Class C, is the object of superclass created??
No. See above.
If you create an instance of C, you will have one object whose most-derived type is C. This object will also be an instanceof B, but it may not behave exactly like a regular B due to method overriding in C and other things.
If yes, how??
Moot.
How to access the private members of class A??
You cannot directly access the private members of a superclass from a subclass. That is what the private access modifier means. If you need to access them you need to use them, you either need to create non-private methods in the superclass to do this (e.g. getters and/or setters), or change the members' access.
(An alternative is to use reflection to override the private access modifiers, but you should only use that as a last resort. It is better to fix the superclass code to provide the required access ... or figure out away that the subclass doesn't need access at all.)
yes, the object of super class is created.
You cannot access the private members of your superclass or else they wont be private. you can have protected or public accessor methods in superclass and that could return the value of your private variables. OR, you could use reflection to access the private variables. But that you could use for anything, not only just superclass.
you can not access private variables outside of the class.
to access them,
1. you may make them public or protected but it is not a good idea.
2. you can write getter method for it which is again not a private method,It is good approach.
3. you may use reflection to access it.
provide more information to help you better
It depends on what language you are using. If you are using C++, you may be able to make the sub-class a friend of the super-class and then you could access its public members. If you you use Java, you could use reflection to locate the super object and reflect on that, but it would be more trouble than it would be worth.

Why can't we create instance of Collections class (not Collection Interface)?

Collections is a public class, then we can call its implicit default constructor. It doesn't have private constructor, which would prevent object creation or force to have static factory method. When I do instantiate as new Collections(), i get error as "Constructor not visible". In short why can't we have instance of java.util.Collections class? Thanks.
From the documentation: "This class consists exclusively of static methods that operate on or return collections."
In other words, Collections is just a collection of methods. An instance of it would not make any sense. It is just like the math functions: You don't have an instance of math, you just use the functions.
It is not an interface as it has concrete methods.
The reason for the "Constructor not visible" message is that the constructor is private (line 73), or at least according to this site . And as others already stated, what would you do with an instance of this class as it only contains static methods
// Suppresses default constructor, ensuring non-instantiability.
private Collections() {
}

Categories

Resources