I want to access the Class Type name in order to specify the runtime type. For example
DAO<?> i = DAO<?> DOA.class.forName(”Student”).newInstance();
What I am trying to do is I have a class called Student and at runtime I want to specify DAO. When running the code I get a ClassCastException.
Is there any way of getting the Student type instead of String so that the following can be done
DAO<?> = new DAO<Student>();
by specifying ?
Related
I implemented an object builder which takes a class name and tries to create a new instance object. The builder tries to inject services if any required. The class name is passed as a string in the current implementation. Here is an example
$className = '\Example\Application\ServiceClass';
$service = CiContext::newInstance($className);
However, this is not compatible with my IDE (eclipse) and the refactoring process does not find the class name (in the string form).
Is there any way to get the class name like java does?
Class classInstance = ServerClass.class;
In this case, the refactoring process finds the class reference and changes the class name.
Well, PHP7 class constant is supported on a class name. For example, the following code is correct in PHP 7.4:
$service = CiContext::newInstance(\Example\Application\ServiceClass::class);
This will solve my problem and the IDE find the class usage.
On the other hand, the class literal is going to support for objects too. For more information see class literal on object
There is a little problem with JavaParser usage.
I've parsed source code file and get all methods from parsed interface. Each method has a few parameters. I can get types of this parameters as string, but I couldn't get original package name or class name of this type. I always get java parser classes names or packages. But I need original package name. En example if parsed method parameter has type String I wont his class name etc.
P.S parsing action is executing in build.gladle before compile task. Reflection is not possible.
Code:
// Create compilation unit for parsed file
CompilationUnit cu = StaticJavaParser.parse(sourceFile);
// Get ClassOrInterfaceDeclaration optional from the compilation unit for parsed file
Optional<ClassOrInterfaceDeclaration> parsedInterfaceOptional =
cu.getInterfaceByName("InterfaceName");
// Get ClassOrInterfaceDeclaration from optional
ClassOrInterfaceDeclaration parsedInterface = parsedInterfaceOptional.get();
for (MethodDeclaration method : parsedInterface.findAll(MethodDeclaration.class)) {
final NodeList<Parameter> parameters = method.getParameters();
// At this step I already have a list of method parameters(parameters).
// I am iterating through the all method parameters and try to get
// original class name or class or package of the parameter type
for (Parameter parameter : parameters) {
// Trying to get original class of the parameter type
Class parameterTypeOriginalClass = parameter.type...
}
Please help if you know how to do it.
Still actual.
JavaParser just parses the provided static source code (i.e. text) so it cannot resolve the actual fully qualified name of the used type. And you cannot get Class from it either. All that you can get using JavaParser is a String with fully qualified name of the used type, e.g. "com.package.Type1"). But you need to do it manually.
For example, you got a string type name "Type1" of the parameter which is "Type1 param"
At first, you need to check if this type is not a primitive type from java.lang. If it does - then the fully qualified name of the type will be java.lang. + type name.
If this is not a primitive, you need to check if this type presents among the import statements of the CompilationUnit. If yes, the fully qualified name of this type can be obtained from the import statement value + type name.
If both first and second items didn't succeed, need to check if an inner class with this type is not declared in this CompilationUnit. If it does - than a fully qualified name will be package of the CompilationUnit + type name.
If even the previous step didn't found anything - need to check if a root class of CompilationUnit extends any superclass or implements any interface and check them correspondingly in the same manner as was checked in item 3.
As you can see, it is not an easy task, but it definitely is a solvable one.
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.
I need to create a method that takes in argument any attribute of any class. But i dont want it to be of type String, to avoid refactoring problems while renaming an attribute and to get the errors in Markers Tab of eclipse, and not while running my application.
Having a class Person :
public class Person {
private String name;
// other attributes...
// getters and setters...
}
Now the needed method :
void getAnAttributeOfAClass( <which_type_or_class_here?> attr_as_arg){
// Now I need to get the name of attribute that would be of class Strin...
}
Is there a function or a method, by which we can specify an attribute?
For example :
Person.class.name
Would it be of class Property ?
EDIT
More exactly (#Smallhacker answer helped me), I need to verify at compile time if the argument is really an attribute of the specified class.
Person.class.name // no compile time error
Person.class.nameXXX // compile time error
The closest to what you want is Reflection API's Field or JavaBeans Introspector API's PropertyDescriptor.
But usually things like that are not needed in Java projects because there are libraries which handle these concerns.
You could pass a Class object along with a String name, then let your method use Introspector internally to read that property.
Not sure I understand you well, but there is a class java.lang.reflect.Field, that has a method getName() that would give your the name of the field.
In your example, to get field name, you would do: Person.class.getDeclaredField("name").
EDIT: to get the value of a field in an object, you would do: field.get(obj);
OK, let's say You have the following variables:
Person person = ...; // initialized with some Person
Field nameField = Person.class.getDeclaredField("name");
Now to get the name of person, you would do:
String personName = (String)nameField.get(person);
Actually, this would throw an exception because name is a private field. You can however bypass the protection by doing:
nameField.setAccessible(true);
Unfortunately, Java lacks an ability to reference member variables in a way that can be analyzed at compile time.
There may be some kind of library to simplify this somewhat, but it wouldn't provide a full solution due to limitations in the language itself.
Maybe java generics can help you with this.
You can do something like:
class YourClass<E> {
void getAnAttributeOfAClass(E attr_as_arg){
// some code
}
}
someVariable = new YourClass<Person>();
someVariable.getAnAtributeOfAClass(someObject); //this will not compile if someObject is not an instance of Person
But I still don't know what you want to do exactly inside the method.
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 );