How to create class from class canonical name in java? - java

I have class canonical name like this dev.ashish.mvc.beans.Employee.
Using this how can i create Class Employee at runtime in order access data members and member functions of Employee.
At runtime i want create class using its canonical name. At times it can be any entity Employee,Customer,User etc.
I tried this :
Class entityClass = Class.forName("dev.ashish.mvc.beans.Employee");
the above code does return class if i do entityClass.getName() it does return me dev.ashish.mvc.beans.Employee but how can i access methods of class Employee .
If i use java reflection like below :
Field field [] = entityClass.getClass().getDeclaredFields();
it returns me declared fields of class java.lang.Class instead of dev.ashish.mvc.beans.Employee
How can i achieve this ???

You already have your class in entityClass, so calling entityClass.getClass() will give you java.lang.Class and entityClass.getClass().getDeclaredFields() will indeed give you methods of Class not of your particular class.
You need:
Field field [] = entityClass.getDeclaredFields();

When you did:
Class entityClass = Class.forName("dev.ashish.mvc.beans.Employee");
you just got class of Employee. Now you have to create instance of it:
Employee employee = (Employee) entityClass.newInstance();
Update:
My answer is wrong. I though you need to work with methods of instance. But you need to access class methods.

You can call a method by name thus (adding to what has already said by others)
Method methodToCall = cls.getMethod("method_name");//cls is of type Class (e.g Employee.class)
methodToCall.invoke(obj, args);//obj is of type Employee in your case
Note that cls is of type Class and you already have to have an instance of the class that you want to call a method on. Note that even if you're calling a method without arguments you still have to pass a class instance (obj in this example), which means that the first argument is always a class instance.

Related

implements with different data type

I have 2 class just call it "Stuff" and "Customer", the classes based on my database table (JDBC) and have abstract class because this 2 classes has same few property(Id,Name), my abstract class containing(Id,Name, along with setter and getter from Id and Name variable).
I was creating 2 more class ("ExecuteStuff" and "ExecuteCustomer") which has a goal to execute a query for manipulate a data in my database,because this situation "ExecuteStuff and ExecuteCustomer" class should have method insert, update,delete and show for manipulate and showing a data from my database, because "ExecuteStuff" and "ExecuteCustomer" need a same method for process a data from my database , I decided to creating my own interface called "myData" which is contain 4 mehod (insertData(), updateData(),deleteData() and showData()) for class "ExecuteStuff" and class "ExecuteCustomer".
My problem is, what type data should I use for parameter inside a method in my interface "myData", for example = public int insertData(Stuff stuff); this method will work for "ExecuteStuff" but not for "ExecuteCustomer" because "ExecuteStuff" and "ExecuteCustomer" has a different object type.
Or a graceful way to solve this problem.
If I understand you correctly, you can use a generic type in your interface. That way it won't matter what the data type of the parameter you pass in is.
Here is a link that explains generics:
https://docs.oracle.com/javase/tutorial/java/generics/types.html
Another solution is to use:
public int insertData(Object obj);
Since both Stuff and Customer are objects.
Hope I was able to help!
You could use a generic parameter:
interface MyData {
public <T> T insertData(T data);
}
Class example:
class MyCustomClassThat implements MyData{
#Override
public <T> T insertData(T data) {
return data;
}
}
This makes the insertData method accept any class. Then you can operate on it however you like. Finally, we return the object originally presented; just in case you operated on the data object itself.

SuperClass and SonClass

I have a SuperClass Employee and a Subclass Manager extends Employee with tribute Name.
Now I want to use instanceof while I go over an array of Employee
Example:
while (employee[i]!=null){
if (employee[i] instanceof Manager)
here is my problem"!!
I want to sysout a Manager atribute "Name":
sysout("Name: "+employee[i].name)
but it says create name in Employee.. why if it extends employee and already used instanceof...I tried Casting like this (Manager)employee[i].name but it doesn't do anything.
The cast needs to be applied to the value on which you are accessing the field.
((Manager)employee[i]).name
You were using it like
(Manager)employee[i].name
which attempted to apply the cast to the value returned by accessing the field name.

How to specify static method as annotation value in Java

I want to provide an annotation as the following:
public #interface CloneField
{
String sourceField();
Class<?> customCloner();
}
Where people can annotation fields on their classes and some framework will automatically copy fields to their classes instances by running a method from the customCloner on an external data source object.
For example:
class Test {
#CloneField(sourceField = "demoTest", customCloner = StringToIntCloner.class)
private int testField;
This will copy a string value from a field named demoTest on the external data source object into an int field on the user's object.
Since the customCloner doesn't hold any data I would want to define the cloning method as static without the need to instantiate it just for calling a method.
Usually I would define the custom cloner class as:
Class <? extends FieldCloner> customCloner;
where FieldCloner has a method for cloning.
But since static methods are not supported on interfaces there isn't a clean way to do so.
Is there an elegant way to do so in Java 7?
Beside the problem of running the method which can be solved by reflection I want to verify at compile time that the customCloner class has the appropriate method for cloning.

How to convert String type to Class type in java

I want to print all the class names in a package and also to print the corresponding attributes and their data types in each package.
In one code, I am able to get the classnames in the form of string.
In another code I am able to get the attributes and their data types using Classname.class.getAttribute();
However I want to merge the two codes. Since in the first code I got the classnames in the form of string , I can't use Classname.class.getAttribute() since here Classname will be of type String.
So I want a method which will convert the "Classname" from String type to Class type.
I tried Class.forName() but it didn't work.
Class<?> classType = Class.forName(className);
Make sure className is fully qualified class name like com.package.class Also, please share your error message that you see.
If the fully-qualified name of a class is available, it is possible to get the corresponding Class using the static method Class.forName().
Eg:
Class c = Class.forName("com.duke.MyLocaleServiceProvider");
Note: Make sure the parameter you provide for the function is fully qualified class name like com.package.class
Check here for any reference.
EDIT:
You could also try using loadClass() method.
Eg:
ClassLoader cl;
Class c = cl.loadClass(name);
It is invoked by the Java virtual machine to resolve class references.
Syntax:
public Class<?> loadClass(String name)
throws ClassNotFoundException
For details on ClassLoader check here
Here
is an implementation of ClassLoader.
Please try as following.
String str = "RequiredClassName";
Class <?> Cref = Class .forName("PackageNaem."+str );

Cast an object dynamically from a string

I'm writing a servlet-filter as the solution of this question:
Is it a good idea to filter inside a JSF template?
now, the idea is to create a big filter to check all privilegies and give the access or not to a certain user.
I create a Map to contains all privilegies for all sub applications and it has the sub application's id (a Long value) as Key and for the value another Map that contains other important informations.
The controller classes are named class1Controller, class2Controller ecc and the subapplications are stored in many folder named class1, class2 ecc...
The last thing that I must say is that all classes have a parameter called applicationID that is the same key of the Map that I mentioned previously.
So, what I would do?
I can retrieve the subapplication visited by the user using getRequestURI() method from HttpServletRequest, the problem is that I should take the application id from the class linked to that application, so I wrote this code:
Long id= ((Class.forName(packageName+applicationName+"Controller"))session.getAttribute(applicationName+"Controller")).getApplicationId();
The problem is that the compiler returns that it can't find method getApplicationId()!
Can I do something to resolve this problem? Or I must find another way to do that?
The last thing that I must say is that all classes have a parameter called applicationID
It sounds like you want an interface with the getApplicationId method in; make all the controllers implement that interface, and then all you need to do is cast to that interface.
// TODO: Work out a better interface name than "Application" :)
Object attribute = session.getAttribute(applicationName+"Controller");
Long id = ((Application) attribute).getApplicationId();
(You might want to use an abstract base class as described by BalusC - they're variations on the same theme, really.)
You're calling getApplicationId() on a Class instance, but it does not have that method at all.
The normal approach is to let all those classes extend some common base abstract class or an interface which has the method definied and then cast to that base abstract class or interface instead.
E.g. with a base abstract class:
public class FooController extends BaseController {}
public class BarController extends BaseController {}
etc..
Where the base abstract class look like this:
public abstract class BaseController {
public Long getApplicationId() {
return applicationId;
}
}
Then you can get it as follows:
Long id = ((BaseController) session.getAttribute(applicationName + "Controller")).getApplicationId();

Categories