Sometimes we call className.methodName() without creating object for it, I mean without using syntax as className objectName = new constructor() and then call as object.methodName()
When to use className.methodName()?
When to call method using object as object.methodName()?
Explanation of above two cases with example will be appreciated.
What you're referring to is a static method.
Assume that I have this :
public class A {
public static void foo(){
System.out.println("Hooray! I work!");
}
}
You can now do this anywhere else in any other class :
A.foo();
This is because the method is static, which means that it can be called on by the CLASS.
This means that it doesn't require an instance of that class in order for the method to be called.
However, even though it isn't required, you can still do this :
A a = new A();
a.foo();
But since the method foo() is static, instantiating an object A is not required in order to run the foo() method.
First. When you're create at least one static method of a class, you can use this method without creating an instance of class. This is useful, for example, for the creation of methods with independent logic. For example:
public class Checker {
public static Boolean month(int value) {
return (value >= 1 && value <= 12);
}
}
You need check correct value of month many times. But what to do each time to create the object. It is much effective to use a static method.
Second. When you create the object, the object is stored in the memory and you get a link to it. Then the object can be used for example to save at the list.
Method at this object is specific. You can save class data and do specific operation with member of this class. For example:
List<Animals> animalsList = new ArrayList<>();
Animal animal = new Animal("dog");
int legs = animal.getCountLegs(); // specific function for object
animalList.add(animal); //save if you need
// use list of object
For every class, we have a Object called as class object which is YourClass.class object. static methods are invoked based on meta-data on those objects. For instances of a class, methods are invoked on the actual instances. Both static and non-static methods are present on method area.
There is no different between 1 and 2 point, because in during compilation compiler makes ClassName.staticMethod() instead of instance.staticMethod().
Static methods in java belong to the class (not an instance of it). They use no instance variables and will usually take input from the parameters, perform actions on it, then return some result. Instances methods are associated with objects and, as the name implies, can use instance variables.
How can I access variable outside a class that extends an other class that is used in an array list? I get an error that says that the variable does not exist in the extended class. Take a look, I want to access the variable members without having to declare it in my Object class:
public abstract class Object {
public int x, y;
}
public class House extends Object {
public int members = 10;
}
// Somewhere else
ArrayList<Object> list = new ArrayList<Object>();
list.add( new House() );
for (Object o : list ) {
o.members;
}
The problem is that in the RTS I'm writing, my Object class has over 40 variables, just because it doesn't work to declare them only in the sub class and access them from outside.
Hope you understand. How can I do this?
You can use instanceof and a cast:
for (Object o : list ) {
if (o instanceof House) {
h = (House) o;
h.members;
}
}
However, this is often considered bad design; you should consider defining an appropriate method in Object (which should really have another name, as others have pointed out) and override it in House. Then, you may call that method on an Object without knowing what kind of object it refers to, and if it is a House, the correct method will be called. (Learning how to do this properly, and when to do it, takes a bit of practice - google polymorphy and overriding.)
First do not name your class Object (see the comments). You cannot access member of an Object in your code, because Object has no field member, House has. But an Object does not have to be a House, so it is not guaranteed that it has member.
If you're sure that in this case youre Object is always a House, cast it:
((House) anObject).member;
This way the compiler assumes that you know more than he does about the actual class of the Object and handles it as if it was a House. You can use instanceof to check if the cast is valid.
Hope you understand that you are using the name for your class as 'Object', which is the parent class for all the classes in Java. Now in your environment there will be two Object classes one which java provides from java.lang.Object and another one you have created. So when you are trying to access your class object and trying to get the attributes of that, it is actually not your class object rather it is an instance of java.lang.Object and hence you are running into an issue.
You have to cast o to a House. E.g. ((House) o).members
just cast the member of arraylist like this
((House)o).members;
I am newbie to java programming language.
My problem is:
I want to read sys.input for a class name from console. Upon reading the name of the class, I want to generate that class automatically and call its method if that class exists already.
my trial is here. Although I dont get any error, nothing happens.
my kind regards.
class s1{
public s1(){
System.out.println(""+ s1.class);
}
}
public class reflection {
public static void main(String[] args) throws IOException, ClassNotFoundException{
System.out.println("enter the class name : ");
BufferedReader reader= new BufferedReader(new InputStreamReader(System.in));
String line = "reflection_N3.";
line+=reader.readLine();
//System.out.println(line);
// "name" is the class name to load
Class clas = Class.forName(line);
clas.getClassLoader();
}
}
You are not creating an instance of the class. Try
Class clas = Class.forName(line);
Object obj = clas.newInstance();
However, the problem is, you can't do much with this object unless you know its exact type, and cast it to that type.
In this example, you could try casting it to your class type, e.g.
if (obj instanceof s1) {
s1 myS1 = (s1) obj;
myS1.s1();
}
However, this hardly works in real life, where you don't know the possible types in advance. The typical solution to this is to define an interface for a specific purpose, and require that the class implements that interface. Then you can downcast the class instance to that interface (throwing an exception if the cast fails), and call its interface methods, without needing to know its concrete type.
Or, as #helios noted, you can use reflection to obtain a method of the loaded class having a specific name.
Btw the Java convention is to start class names with uppercase, hence S1 and Reflection.
You're only obtaining the ClassLoader, you're never actually constructing an object of the specified class.
Use clas.newInstance() if you want to call the default constructor, or investigate Class.getConstructor(...) if you need to call a specific constructor.
Let's say we have 2 classes A and B
public class A{
private int member1;
A() {
member1 = 10;
}
public getMember(){
return member1;
}
}
Class B is also on the same lines except that its member variable is named member2 and gets intitialized to say 20 inside the constructor.
My Requirement :
At runtime , I get a string which contains a className ( could be A or B). I want to dynamically create an object of this class along with invoking the constructor. How can I achieve this . I don't want to use interfaces for common functionality of above classes Morever, later on I set the properties of this raw object using Propery Builder Bean Util class based on a list of columns .
Class clazz = Class.forName("className");
Obj obj = clazz.newInstance();
How I can dynamically convert that obj to className object.
How can I achieve this . I don't want to use interfaces for common functionality of above classes
Then the answer is very simple and you won’t like it: you can’t. You want to modify the static type of the variables which is, by definition, determined at compile time. Changing it at runtime is not possible.
What do you mean with "dynamically convert"? It IS an object of type "className", stored in a variable of type Object. If you want to use it as an object of type A, you have to cast it, and for example store it in a variable of type A.
Class Class has a cast method which at first sight seems to be doing just what you want. So you could try
... = clazz.cast(obj);
but what would be the return type??? It should be either A or B, but you can't declare a variable dynamically...
So I see no other way than the ugly, but tried and true
if (obj instanceof A) {
A a = (A) obj;
...
} else if (obj instanceof B) {
B b = (B) obj;
...
}
Note that if with bean introspection, you can always see the actual dynamic type and internals of the object, so I see not much point trying to get a static reference of the right type to it.
I would like to do dynamic casting for a Java variable, the casting type is stored in a different variable.
This is the regular casting:
String a = (String) 5;
This is what I want:
String theType = 'String';
String a = (theType) 5;
Is this possible, and if so how? Thanks!
Update
I'm trying to populate a class with a HashMap that I received.
This is the constructor:
public ConnectParams(HashMap<String,Object> obj) {
for (Map.Entry<String, Object> entry : obj.entrySet()) {
try {
Field f = this.getClass().getField(entry.getKey());
f.set(this, entry.getValue()); /* <= CASTING PROBLEM */
} catch (NoSuchFieldException ex) {
log.error("did not find field '" + entry.getKey() + '"');
} catch (IllegalAccessException ex) {
log.error(ex.getMessage());
}
}
}
The problem here is that some of the class' variables are of type Double, and if the number 3 is received it sees it as Integer and I have type problem.
Yes it is possible using Reflection
Object something = "something";
String theType = "java.lang.String";
Class<?> theClass = Class.forName(theType);
Object obj = theClass.cast(something);
but that doesn't make much sense since the resulting object must be saved in a variable of Object type. If you need the variable be of a given class, you can just cast to that class.
If you want to obtain a given class, Number for example:
Object something = new Integer(123);
String theType = "java.lang.Number";
Class<? extends Number> theClass = Class.forName(theType).asSubclass(Number.class);
Number obj = theClass.cast(something);
but there is still no point doing it so, you could just cast to Number.
Casting of an object does NOT change anything; it is just the way the compiler treats it.
The only reason to do something like that is to check if the object is an instance of the given class or of any subclass of it, but that would be better done using instanceof or Class.isInstance().
Update
according your last update the real problem is that you have an Integer in your HashMap that should be assigned to a Double. What you can do in this case, is check the type of the field and use the xxxValue() methods of Number
...
Field f = this.getClass().getField(entry.getKey());
Object value = entry.getValue();
if (Integer.class.isAssignableFrom(f.getType())) {
value = Integer.valueOf(((Number) entry.getValue()).intValue());
} else if (Double.class.isAssignableFrom(f.getType())) {
value = Double.valueOf(((Number) entry.getValue()).doubleValue());
} // other cases as needed (Long, Float, ...)
f.set(this, value);
...
(not sure if I like the idea of having the wrong type in the Map)
You'll need to write sort of ObjectConverter for this. This is doable if you have both the object which you want to convert and you know the target class to which you'd like to convert to. In this particular case you can get the target class by Field#getDeclaringClass().
You can find here an example of such an ObjectConverter. It should give you the base idea. If you want more conversion possibilities, just add more methods to it with the desired argument and return type.
Regarding your update, the only way to solve this in Java is to write code that covers all cases with lots of if and else and instanceof expressions. What you attempt to do looks as if are used to program with dynamic languages. In static languages, what you attempt to do is almost impossible and one would probably choose a totally different approach for what you attempt to do. Static languages are just not as flexible as dynamic ones :)
Good examples of Java best practice are the answer by BalusC (ie ObjectConverter) and the answer by Andreas_D (ie Adapter) below.
That does not make sense, in
String a = (theType) 5;
the type of a is statically bound to be String so it does not make any sense to have a dynamic cast to this static type.
PS: The first line of your example could be written as Class<String> stringClass = String.class; but still, you cannot use stringClass to cast variables.
You can do this using the Class.cast() method, which dynamically casts the supplied parameter to the type of the class instance you have. To get the class instance of a particular field, you use the getType() method on the field in question. I've given an example below, but note that it omits all error handling and shouldn't be used unmodified.
public class Test {
public String var1;
public Integer var2;
}
public class Main {
public static void main(String[] args) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
map.put("var1", "test");
map.put("var2", 1);
Test t = new Test();
for (Map.Entry<String, Object> entry : map.entrySet()) {
Field f = Test.class.getField(entry.getKey());
f.set(t, f.getType().cast(entry.getValue()));
}
System.out.println(t.var1);
System.out.println(t.var2);
}
}
You can write a simple castMethod like the one below.
private <T> T castObject(Class<T> clazz, Object object) {
return (T) object;
}
In your method you should be using it like
public ConnectParams(HashMap<String,Object> object) {
for (Map.Entry<String, Object> entry : object.entrySet()) {
try {
Field f = this.getClass().getField(entry.getKey());
f.set(this, castObject(entry.getValue().getClass(), entry.getValue()); /* <= CASTING PROBLEM */
} catch (NoSuchFieldException ex) {
log.error("did not find field '" + entry.getKey() + '"');
} catch (IllegalAccessException ex) {
log.error(ex.getMessage());
}
}
}
It works and there's even a common pattern for your approach: the Adapter pattern. But of course, (1) it does not work for casting java primitives to objects and (2) the class has to be adaptable (usually by implementing a custom interface).
With this pattern you could do something like:
Wolf bigBadWolf = new Wolf();
Sheep sheep = (Sheep) bigBadWolf.getAdapter(Sheep.class);
and the getAdapter method in Wolf class:
public Object getAdapter(Class clazz) {
if (clazz.equals(Sheep.class)) {
// return a Sheep implementation
return getWolfDressedAsSheep(this);
}
if (clazz.equals(String.class)) {
// return a String
return this.getName();
}
return null; // not adaptable
}
For you special idea - that is impossible. You can't use a String value for casting.
Your problem is not the lack of "dynamic casting". Casting Integer to Double isn't possible at all. You seem to want to give Java an object of one type, a field of a possibly incompatible type, and have it somehow automatically figure out how to convert between the types.
This kind of thing is anathema to a strongly typed language like Java, and IMO for very good reasons.
What are you actually trying to do? All that use of reflection looks pretty fishy.
Don't do this. Just have a properly parameterized constructor instead. The set and types of the connection parameters are fixed anyway, so there is no point in doing this all dynamically.
For what it is worth, most scripting languages (like Perl) and non-static compile-time languages (like Pick) support automatic run-time dynamic String to (relatively arbitrary) object conversions. This CAN be accomplished in Java as well without losing type-safety and the good stuff statically-typed languages provide WITHOUT the nasty side-effects of some of the other languages that do evil things with dynamic casting. A Perl example that does some questionable math:
print ++($foo = '99'); # prints '100'
print ++($foo = 'a0'); # prints 'a1'
In Java, this is better accomplished (IMHO) by using a method I call "cross-casting".
With cross-casting, reflection is used in a lazy-loaded cache of constructors and methods that are dynamically discovered via the following static method:
Object fromString (String value, Class targetClass)
Unfortunately, no built-in Java methods such as Class.cast() will do this for String to BigDecimal or String to Integer or any other conversion where there is no supporting class hierarchy. For my part, the point is to provide a fully dynamic way to achieve this - for which I don't think the prior reference is the right approach - having to code every conversion. Simply put, the implementation is just to cast-from-string if it is legal/possible.
So the solution is simple reflection looking for public Members of either:
STRING_CLASS_ARRAY = (new Class[] {String.class});
a) Member member = targetClass.getMethod(method.getName(),STRING_CLASS_ARRAY);
b) Member member = targetClass.getConstructor(STRING_CLASS_ARRAY);
You will find that all of the primitives (Integer, Long, etc) and all of the basics (BigInteger, BigDecimal, etc) and even java.regex.Pattern are all covered via this approach. I have used this with significant success on production projects where there are a huge amount of arbitrary String value inputs where some more strict checking was needed. In this approach, if there is no method or when the method is invoked an exception is thrown (because it is an illegal value such as a non-numeric input to a BigDecimal or illegal RegEx for a Pattern), that provides the checking specific to the target class inherent logic.
There are some downsides to this:
1) You need to understand reflection well (this is a little complicated and not for novices).
2) Some of the Java classes and indeed 3rd-party libraries are (surprise) not coded properly. That is, there are methods that take a single string argument as input and return an instance of the target class but it isn't what you think... Consider the Integer class:
static Integer getInteger(String nm)
Determines the integer value of the system property with the specified name.
The above method really has nothing to do with Integers as objects wrapping primitives ints.
Reflection will find this as a possible candidate for creating an Integer from a String incorrectly versus the decode, valueof and constructor Members - which are all suitable for most arbitrary String conversions where you really don't have control over your input data but just want to know if it is possible an Integer.
To remedy the above, looking for methods that throw Exceptions is a good start because invalid input values that create instances of such objects should throw an Exception. Unfortunately, implementations vary as to whether the Exceptions are declared as checked or not. Integer.valueOf(String) throws a checked NumberFormatException for example, but Pattern.compile() exceptions are not found during reflection lookups. Again, not a failing of this dynamic "cross-casting" approach I think so much as a very non-standard implementation for exception declarations in object creation methods.
If anyone would like more details on how the above was implemented, let me know but I think this solution is much more flexible/extensible and with less code without losing the good parts of type-safety. Of course it is always best to "know thy data" but as many of us find, we are sometimes only recipients of unmanaged content and have to do the best we can to use it properly.
Cheers.
So, this is an old post, however I think I can contribute something to it.
You can always do something like this:
package com.dyna.test;
import java.io.File;
import java.lang.reflect.Constructor;
public class DynamicClass{
#SuppressWarnings("unchecked")
public Object castDynamicClass(String className, String value){
Class<?> dynamicClass;
try
{
//We get the actual .class object associated with the specified name
dynamicClass = Class.forName(className);
/* We get the constructor that received only
a String as a parameter, since the value to be used is a String, but we could
easily change this to be "dynamic" as well, getting the Constructor signature from
the same datasource we get the values from */
Constructor<?> cons =
(Constructor<?>) dynamicClass.getConstructor(new Class<?>[]{String.class});
/*We generate our object, without knowing until runtime
what type it will be, and we place it in an Object as
any Java object extends the Object class) */
Object object = (Object) cons.newInstance(new Object[]{value});
return object;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public static void main(String[] args)
{
DynamicClass dynaClass = new DynamicClass();
/*
We specify the type of class that should be used to represent
the value "3.0", in this case a Double. Both these parameters
you can get from a file, or a network stream for example. */
System.out.println(dynaClass.castDynamicClass("java.lang.Double", "3.0"));
/*
We specify a different value and type, and it will work as
expected, printing 3.0 in the above case and the test path in the one below, as the Double.toString() and
File.toString() would do. */
System.out.println(dynaClass.castDynamicClass("java.io.File", "C:\\testpath"));
}
Of course, this is not really dynamic casting, as in other languages (Python for example), because java is a statically typed lang. However, this can solve some fringe cases where you actually need to load some data in different ways, depending on some identifier. Also, the part where you get a constructor with a String parameter could be probably made more flexible, by having that parameter passed from the same data source. I.e. from a file, you get the constructor signature you want to use, and the list of values to be used, that way you pair up, say, the first parameter is a String, with the first object, casting it as a String, next object is an Integer, etc, but somehwere along the execution of your program, you get now a File object first, then a Double, etc.
In this way, you can account for those cases, and make a somewhat "dynamic" casting on-the-fly.
Hope this helps anyone as this keeps turning up in Google searches.
Try this for Dynamic Casting. It will work!!!
String something = "1234";
String theType = "java.lang.Integer";
Class<?> theClass = Class.forName(theType);
Constructor<?> cons = theClass.getConstructor(String.class);
Object ob = cons.newInstance(something);
System.out.println(ob.equals(1234));
I recently felt like I had to do this too, but then found another way which possibly makes my code look neater, and uses better OOP.
I have many sibling classes that each implement a certain method doSomething(). In order to access that method, I would have to have an instance of that class first, but I created a superclass for all my sibling classes and now I can access the method from the superclass.
Below I show two ways alternative ways to "dynamic casting".
// Method 1.
mFragment = getFragmentManager().findFragmentByTag(MyHelper.getName(mUnitNum));
switch (mUnitNum) {
case 0:
((MyFragment0) mFragment).sortNames(sortOptionNum);
break;
case 1:
((MyFragment1) mFragment).sortNames(sortOptionNum);
break;
case 2:
((MyFragment2) mFragment).sortNames(sortOptionNum);
break;
}
and my currently used method,
// Method 2.
mSuperFragment = (MySuperFragment) getFragmentManager().findFragmentByTag(MyHelper.getName(mUnitNum));
mSuperFragment.sortNames(sortOptionNum);
Just thought I would post something that I found quite useful and could be possible for someone who experiences similar needs.
The following method was a method I wrote for my JavaFX application to avoid having to cast and also avoid writing if object x instance of object b statements every time the controller was returned.
public <U> Optional<U> getController(Class<U> castKlazz){
try {
return Optional.of(fxmlLoader.<U>getController());
}catch (Exception e){
e.printStackTrace();
}
return Optional.empty();
}
The method declaration for obtaining the controller was
public <T> T getController()
By using type U passed into my method via the class object, it could be forwarded to the method get controller to tell it what type of object to return. An optional object is returned in case the wrong class is supplied and an exception occurs in which case an empty optional will be returned which we can check for.
This is what the final call to the method looked like (if present of the optional object returned takes a Consumer
getController(LoadController.class).ifPresent(controller->controller.onNotifyComplete());