1

I have a base class with a public method.

`public class ClassA {
   private int a;
   public void setA() {
    a = 15;
    System.out.println(a);
   }
 }`

Then, there is a ClassB which extends ClassA,

`public class ClassB extends ClassA {
   public void test() {
      setA();
   }
 }`

Now, in main() I create an instance of ClassB. The method setA() and test() is not accessible by the instance.

`public static void main( String[] args ) throws IllegalAccessException, InstantiationException {
   Class<?> cls = ClassB.class;
   Object obj = cls.newInstance();
   obj.setA(); //Not Accessible
   obj.test(); //Not Accessible

}`

Can someone tell me where I am going wrong?

Sathya
  • 58
  • 6
  • `Object` does not have the methods `test` or `setA`. You need to cast your Object to `ClassB`. – Ben May 24 '18 at 10:21
  • https://stackoverflow.com/questions/5306835/casting-objects-in-java – jhamon May 24 '18 at 10:21
  • 3
    Also, may we ask why you are using reflection here instead of normal instantiation? – Tim Biegeleisen May 24 '18 at 10:21
  • Is there any specific reason why you create your instance with .newInstance() instead of doing the simple `ClassB b = new ClassB()`? – OH GOD SPIDERS May 24 '18 at 10:22
  • in which class are you creating main() method. – rishabhkeshari123 May 24 '18 at 10:24
  • Use ClassB obj = (ClassB) cls.newInstance(); instead Object obj = cls.newInstance(); or you can use... Class cls = ClassB.class; – Sree May 24 '18 at 10:26
  • In my project, Initially i have to get all classes that has a custom annotation. Once it is done, I have to instantiate the classes and store some values in the base class. So later on, when i invoke a method from derived class it makes use of the values stored to perform its logic. So, now I have only the Class> data type variable. (i.e.) only cls variable and I can create obj. Can someone tell me how can I do the casting here? – Sathya May 24 '18 at 10:34

5 Answers5

0

As already answered in comments, you should Cast obj to Class:

public static void main( String[] args ) throws IllegalAccessException, InstantiationException {
           Class<?> cls = ClassB.class;
           Object obj = cls.newInstance();
           ((ClassB) obj).setA();
           ((ClassA) obj).setA();
           ((ClassB) obj).test();

        }
Abhishek
  • 688
  • 6
  • 21
0

You're creating a new Object by calling cls.newInstance(). However since we are certain that the returned object will be of our wanted class we can cast it without any issues:

public static void main( String[] args ) throws IllegalAccessException, InstantiationException {
   Class<?> cls = ClassB.class;
   ClassB obj = (ClassB)cls.newInstance();
   obj.setA(); //Accessible now
   obj.test(); //Accessible now

}

Without the cast to ClassB the returned object will be treated as an java.lang.Object and therefore does only contain the methods defined by it.

But as most comments already stated it is often times much more easier to simply create a new instance of a type using the new operator:

public static void main( String[] args ) {
   ClassB obj = new ClassB();
   obj.setA(); //Accessible now
   obj.test(); //Accessible now

}
L.Spillner
  • 1,772
  • 10
  • 19
0

You can instantiate obj normally with ClassB obj = new ClassB();

You can try something like this:

ClassB obj = new ClassB();
obj.setA(); //Accessible
obj.test(); //Accessible

Or, to further improve Abhishek's answer:

  Class<?> cls = ClassB.class;
  ClassB obj = (ClassB) cls.newInstance();
  obj.setA();
  obj.setA();
  obj.test();

Note: This creates obj of type ClassB. If you need it in Object type only, you can do cast it to ClassB type every single time like this:

 Class<?> cls = ClassB.class;
 Object obj = cls.newInstance();
 ((ClassB) obj).setA();
 ((ClassA) obj).setA();
 ((ClassB) obj).test();

If this is what you meant to ask in a comment, it is possible to do the typecasting if you know only cls:

Class<?> cls = ClassB.class;
Object obj = cls.newInstance();
ClassB.class.cast(obj).setA();
ClassB.class.cast(obj).setA();
ClassB.class.cast(obj).test();
  • Actually what I was trying to ask in the comment is, if suppose the variable cls is passed as an argument, how can we do the type casting. – Sathya May 24 '18 at 10:51
  • `public void testMethod(Class> cls) { Object obj = cls.newInstance(); obj.setA(); //Not Accessible obj.test(); //Not Accessible }` – Sathya May 24 '18 at 10:53
  • https://stackoverflow.com/a/2127384/5058312 - I think you're looking for something like this – Ramya Ramanathan May 24 '18 at 11:10
0

Object is base class of all classes but in this case, it does not know setA() method and test() method. You can do as follow.

Class<?> cls = ClassB.class;
Object obj = cls.newInstance();
(ClassB)obj.setA(); 
(ClassB)obj.test(); 
TaQuangTu
  • 2,155
  • 2
  • 16
  • 30
0
class ClassA {
       private int a;

       public void setA() {
        a = 15;
        System.out.println(a);
       }
     }

      class ClassB extends ClassA {
          public static void main( String[] args ) throws IllegalAccessException, InstantiationException {
               Class cls = ClassB.class;
               ClassB obj = (ClassB) cls.newInstance();
               obj.setA(); //Accessible
               obj.test(); // Accessible

            }
           public void test() {
              setA();
           }
         }

It should be like this.

You want to instantiate a class by it's name?

First of all, you need to make a Class object:

Class cls = Class.forName(strClassName); Then instantiate this (note, this can throw various exceptions - access violation, ClassNotFound, no public constructor without arguments etc.)

Object instance = cls.newInstance();

Then you can cast it:

return (SomeClass) instance; Please make sure you understand the differences between:

A class name (approximately a file name) A class object (essentially a type information) A class instance (an actual object of this type) You can also cast the cls object to have type Class, if you want. It doesn't give you much, though. And you can inline it, to:

return (SomeClass)(Class.forName(strClassName).newInstance()); Oh, but you can do type checking with the cls object, before instantiating it. So you only instanciate it, if it satisfies your API (implements the interface you want to get).

EDIT: add further example code, towards reflection.

For example:

if (cls.isInstance(request)) {
  // ...
}
  • But then why to use reflection instead of simple instantiation. – bit-shashank May 24 '18 at 10:32
  • absolutely right but we can achieve object many way, so she is using reflection. – rishabhkeshari123 May 24 '18 at 10:34
  • I use reflection here because my project demands it. Is there a way to get "ClassB" to do the typecasting if I only have the cls variable @rishabhkeshari123 – Sathya May 24 '18 at 10:40
  • if (cls.isInstance(ClassB.class)) { //then do casting } – rishabhkeshari123 May 24 '18 at 10:51
  • Sathya first of all you have to load the class either by using forname method or Class cls = ClassB.class; like this then only you will get the instance of ClassB. to typecast – rishabhkeshari123 May 24 '18 at 10:57
  • public void testMethod (Class> cls) { Object obj = cls.newInstance(); obj.setA(); //Not Accessible obj.test(); //Not Accessible }` If this is the case, how can I do the typecasting? @rishabhkeshari123 – Sathya May 24 '18 at 11:01