How to store a reference to a class in Java? - java

Is there any way in Java to store a reference to a class? Here's what I want to do:
public class Foo
{
public static void doSomething() {...}
};
SomeClass obj = Foo;
obj.doSomething();
Is there some class "SomeClass" which lets me store a reference to a class, such that I can later use that stored object to call a static member of the original class?
The obvious thing would be class Class:
Class obj = Foo.class;
obj.someMember().doSomething();
but I haven't figured out which of class Class's members might act as "someMember()"... none of them, I think.
Does anyone know if what I'm trying to do is possible in Java?

You can dynamically get a method from a Class object using the getMethod() methods on the class. If a method is static, then the "object" parameter of "invoke" will be null.
For example, the "obj.someMember()" above would be something like this:
obj.getMethod("someMember", null).invoke(null, null);
The extra nulls are because your method requires no parameters. If your method takes parameters, then they will need to be passed in accordingly.
This will throw various checked exceptions, so you'll need to handle those as well.
Once you've invoked the method, it will return an Object. You'll want to cast that to whatever type you're expecting, and then you'll be able to run the "doSomething()" method directly on that.
This is using a trick called reflection, if you'd like to read up more on it. :)

If you are using jdk1.5 or above, annotation will be a choice when you want to get metadata of Class.

Related

Safeguarding method parameters in java

I want to safe guard my method parameters that were passed to the called method from being changed accidentally. I know that we can use final keyword to achieve this (partially) like the following in the method signature.
public void someMethod(final int intVal, final MyClass myobj){}
With the help of the above signature I cannot change the value of intVal, but however I can change the values (members) of myobj (I can safe guard only the reference not being changed, but not the members of the referencing object, that why I said partial).
Now I am looking to safe guard my myobj members either, getting changed in the called method someMethod.
In my knowledge I could achieve this using the following ways
Create an immutable class and pass it as a parameter
Deep copy the object and send the cloned object to the method.
Is there any better apporach to safeguard the method parameters?

reference a method from a class by using a variable

I know how in Java, a class is referenced like com.google.googlemaps.exampleClass.exampleMethod().
Is it possible to interchange the first parts of the referenece (in this case, the com.google.googlemaps) using a variable (Class c)?
EDIT
Ok, after some confusion, I'm going to (try to) provide an example
We have Class A. I can add a new instance of it. Each instance has the variables name (a String), and redir (currently in turmoil). redir is the variable which is supposed to hold the reference for the class, so I can call a specific method from those classes, so redir is like com.google.googlemaps etc.
Like c.exampleMethod()?
Yes, like so
import com.google.googlemaps.ExampleClass;
...
ExampleClass c = new ExampleClass();
c.exampleMethod();
from your example:
com.google.googlemaps.exampleClass.exampleMethod()
the exampleMethod() is a static method.
If you have an object/reference with Type Class<com.google.googlemaps.exampleClass> (Class c) you can call getMethod to get the Method object. And then you could call invoke method to invoke the method.

Working with the class keyword in Java

I don't really understand how the class keywords work in some instances.
For example, the get(ClientResponse.class) method takes the ClientResponse.class. How does it use this when it gets it, and what are the advantages over just passing an instance of it?
SomeClass.class
returns a Java Class object. Class is genericized, so the actual type of SomeClass.class will be Class<SomeType> .
There are lots of uses for this object, and you can read the Javadoc for it here: http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html
In ClientResponse.class, class is not a keyword, neither a static field in the class ClientResponse.
The keyword is the one that we use to define a class in Java. e.g.
public class MyClass { } /* class used here is one of the keywords in Java */
The class in ClientResponse.class is a short-cut to the instance of Class<T> that represents the class ClientResponse.
There is another way to get to that instance for which you need an instance of ClientResponse. e.g
ClientResponse obj = new ClientResponse();
Class clazz = obj.getClass();
what are the advantage over just passing a instance of it?
In the above example you can see what would happen in case obj was null (an NPE). Then there would be no way for the method to get the reference to the Class instance for ClientResponse.
The Class class, which is different from the class keyword, is meta-data describing instances. It tells you about the methods, data members, constructors, and other features of the instances that you create by calling new.
For example get(ClientResponse.class) method takes the
ClientResponse.class how does it uses this when it gets it and what
are the advantage over just passing a instance of it?
You can't pass an instance of ClientResponse to this method; it's expecting meta-data about all instances of ClientResponse. If you passed an instance, you'd expect that the method might change the state of that instance. But passing the meta-data about all instances might allow the method to create a new kind of instance (e.g. a dynamic proxy) or do something else that depends on the meta-data about all instances of ClientResponse. See the difference?
A class is a "blueprint" of the object. The instance is a object.
If we have
public class SomeClass {
int a;
SomeClass(int a) {
this.a = a
}
}
We can have an instance of this class
SomeClass c = new SomeClass(10);
c is an instance of the class. It has a integer a with value 10.
The object SomeClass.class represents a Class.
Here SomeClass.class is a object of the type Class which has the information that SomeClass is
a concrete class with
one constructor
with a integer member variable
and lots more other metadata about the class SomeClass. Note that it does not have a value for a.
You should use get(c) incase you are planning to do something with a instance of c like call c.a or other useful functions to manupulate/get data of the instance.
You should use get(SomeClass.class) when the get returns something based on the fact that the argument is some type of class. For example, if this is a method on a Registry class which has a map which retrieves a implementation class based on type of class passed in.
The very most important fact is - you don't need to have an instance to call the method. It's critically useful in situations when you cannot for some reason instantiate a class, e.g. it's abstract, or have only private constructor, or can only be correctly instantiated by some framework, like Spring or JSF.
You can then call get to obtain an object of a requested type without even knowing where it does come from and how it get's created.
Here ClientResponse.class is an instance of Class<ClientResponse>. In general Class object represents type of an object. When you create new instance:
Object obj = new ClientResponse()
you can retrieve the class (type) of that object by calling:
obj.getClass()
So, why would you pass Class objects around? It's less common, but one reason is to allow some method create arbitrary number of instances of a given class:
ClientResponse resp = ClientResponse.newInstance();
There's a lot of ways Class objects can be used. This is used for Reflection. Below is a link that can help you understand more.
http://docs.oracle.com/javase/tutorial/reflect/class/classNew.html
Whenever we compile any Java file, the compiler will embed a public, static, final field named class, of the type java.lang.Class, in the emitted byte code. Since this field is public and static, we can access it using dotted notation along with class name as in your case it is ClientResponse.class.

Java: How To Call Non Static Method From Main Method?

I'm learning java and now i've the following problem: I have the main method declared as
public static void main(String[] args) {
..... }
Inside my main method, because it is static I can call ONLY other static method!!! Why ?
For example: I have another class
public class ReportHandler {
private Connection conn;
private PreparedStatement prep;
public void executeBatchInsert() { ....
} }
So in my main class I declare a private ReportHandler rh = new ReportHandler();
But I can't call any method if they aren't static.
Where does this go wrong?
EDIT: sorry, my question is: how to 'design' the app to allow me to call other class from my 'starting point' (the static void main).
You simply need to create an instance of ReportHandler:
ReportHandler rh = new ReportHandler(/* constructor args here */);
rh.executeBatchInsert(); // Having fixed name to follow conventions
The important point of instance methods is that they're meant to be specific to a particular instance of the class... so you'll need to create an instance first. That way the instance will have access to the right connection and prepared statement in your case. Just calling ReportHandler.executeBatchInsert, there isn't enough context.
It's really important that you understand that:
Instance methods (and fields etc) relate to a particular instance
Static methods and fields relate to the type itself, not a particular instance
Once you understand that fundamental difference, it makes sense that you can't call an instance method without creating an instance... For example, it makes sense to ask, "What is the height of that person?" (for a specific person) but it doesn't make sense to ask, "What is the height of Person?" (without specifying a person).
Assuming you're leaning Java from a book or tutorial, you should read up on more examples of static and non-static methods etc - it's a vital distinction to understand, and you'll have all kinds of problems until you've understood it.
Please find answer:
public class Customer {
public static void main(String[] args) {
Customer customer=new Customer();
customer.business();
}
public void business(){
System.out.println("Hi Harry");
}
}
Java is a kind of object-oriented programming, not a procedure programming. So every thing in your code should be manipulating an object.
public static void main is only the entry of your program. It does not involve any object behind.
So what is coding with an object? It is simple, you need to create a particular object/instance, call their methods to change their states, or do other specific function within that object.
e.g. just like
private ReportHandler rh = new ReportHandler();
rh.<function declare in your Report Handler class>
So when you declare a static method, it doesn't associate with your object/instance of your object. And it is also violate with your O-O programming.
static method is usually be called when that function is not related to any object behind.
You can't call a non-static method from a static method, because the definition of "non-static" means something that is associated with an instance of the class. You don't have an instance of the class in a static context.
A static method means that you don't need to invoke the method on an instance. A non-static (instance) method requires that you invoke it on an instance. So think about it: if I have a method changeThisItemToTheColorBlue() and I try to run it from the main method, what instance would it change? It doesn't know. You can run an instance method on an instance, like someItem.changeThisItemToTheColorBlue().
More information at http://en.wikipedia.org/wiki/Method_(computer_programming)#Static_methods.
You can think of a static member function as one that exists without the need for an object to exist. For example, the Integer.parseInt() method from the Integer class is static. When you need to use it, you don't need to create a new Integer object, you simply call it. The same thing for main(). If you need to call a non-static member from it, simply put your main code in a class and then from main create a new object of your newly created class.
You cannot call a non-static method from the main without instance creation, whereas you can simply call a static method.
The main logic behind this is that, whenever you execute a .class file all the static data gets stored in the RAM and however, JVM(java virtual machine) would be creating context of the mentioned class which contains all the static data of the class.
Therefore, it is easy to access the static data from the class without instance creation.The object contains the non-static data
Context is created only once, whereas object can be created any number of times.
context contains methods, variables etc. Whereas, object contains only data.
thus, the an object can access both static and non-static data from the context of the class
Since you want to call a non-static method from main, you just need to create an object of that class consisting non-static method and then you will be able to call the method using objectname.methodname();
But if you write the method as static then you won't need to create object and you will be able to call the method using methodname(); from main. And this will be more efficient as it will take less memory than the object created without static method.
Useful link to understand static keyword
https://www.codeguru.com/java/tij/tij0037.shtml#Heading79

Invoking dynamic Method without known Constructor?

If I do this in Java to call a method name from a class dynamically, it works.
MainApp app = new MainApp();
Method meth = app.getClass().getMethod("myMethod", MyParameterType.class);
//call method
meth.invoke(app, new MyParameterType("hello"));
But this worked because I know the constructor in the invoke method. But if I were to pass the Method object as a parameter to some other classes, and I don't know who is the constructor, I cannot invoke the method any more. Even if I know, I may not want to create a different object to just make a call to the method. For eg:
//This is in the class call MainApp.java.
//There is a method in MainApp.java that looks this way: myMethod(MyParameterType param);
MainApp app = new MainApp();
OtherClass myClass = new OtherClass();
Method meth = app.getClass().getMethod("myMethod", MyParameterType.class);
myClass.callMe(meth);
//Inside OtherClass.java
public void callMe(Method meth) {
//call method
meth.invoke(########, new MyParameterType("hello"));
}
In this case, what should I put for the ######## parameter? Within the context of OtherClass.java, the base constructor object wouldn't be known. And why would I need if since meth is already a Method type that I just call like a function?
Thanks
Assuming it's an instance method, you've got to have an instance to call the method on, just like anything else. How you get hold of that instance will depend on what you're trying to do; you could pass in a Constructor, or a reference to an existing object, or some interface which will create the instance when you ask it to... we can't really give you any advice on which approach is the most suitable without knowing what you're trying to do.
If it's a static method, you can pass null for the first argument.
What it seems you are looking for or thinking about is the concept of `lambda functions``. Those can be called in isolation.
A Method type is not a standalone method, but more like a 'path' into an object. Compare this with a relative URL like /subscribe.html. Out of context this is pretty useless, but when bundled with a site like www.example.com it makes sense.
As such, Method can only be used in combination with an instance. (edit: as John mentioned, unless it's a static method of course which do not need instances)
If you can safely invoke a method without providing an instance, it should be a static method, in which case any instance provided is ignored, you can give it null.
If you have to provide an instance of the object, there is no way around this.
If the developer who write the method has labelled it non-static incorrectly, I suggest you discuss with them why they did it.

Categories