Hello. I am trying to input the name of a class that I have imported already, and can instantiate regularly, such as 'myClass inst = new myClass('foo');' and create a new instance-object of that class. The code below illustrates my question more specifically:

import java.lang.reflect.*;
import java.io.*;

public class reflecting1
{
   public reflecting1()
   {
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Input the name? \n");

        try
        {
           typed = reader.readLine();
        } catch (Exception e) {}
    
       
       try
       { 
         Constructor con = (typed.class).getConstructor(String.class);
       
         Object obj = con.newInstance("Hello World!");
         Method methd = (typed.class).getMethod("hashCode");

         System.out.println(obj);

         int hash = methd.invoke(obj);
         System.out.println(hash + "");
            
        } catch (Exception ee) {
        System.err.println("Class not created.");
        
        }
        
    }
    
}

When the input of the above program is: 'String'
Why is the output not:
"
Hello World!
-969099747
"

and I tried:

import java.lang.reflect.*;
import java.io.*;

public class reflecting2
{
   public reflecting2()
   {
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Input the name? \n");

        try
        {
           typed = reader.readLine();
        } catch (Exception e) {}
    
       
       try
       { 
         Class newC = Class.nameOf(typed);
         Constructor con = (typed.class).getConstructor(String.class);
       
         Object obj = con.newInstance("Hello World!");
         Method methd = (typed.class).getMethod("hashCode");

         System.out.println(obj);

         int hash = methd.invoke(obj);
         System.out.println(hash + "");
            
        } catch (Exception ee) {
        System.err.println("Class not created.");
        
        }
        
    }
    
}

but still didn't work.. does anyone know how to make this work?

Recommended Answers

All 14 Replies

Can you show what the printed output from when you executed the code?
What .class files were in the directory when you executed the code?

does anyone know how to make this work?

Neither of the posted code compiles.
Fix the compilation errors.

... or lust have a look at this:

class MyClass {

   private String name;

   public MyClass() {
      name = "no name";
   }

   public MyClass(String name) {
      this.name = name;
   }

   @Override
   public String toString() {
      return "An instance of MyClass " + name;
   }
}

public class Demo {

   public static void main(String[] args) {
      
      Class<?> theClass;
      java.lang.reflect.Constructor<?> constructor;
      Object newObject;

      try {
         
         theClass = Class.forName("MyClass");

         constructor = theClass.getConstructor(); // default constructor
         newObject = constructor.newInstance();
         System.out.println(newObject);

         constructor = theClass.getConstructor(String.class);
         newObject = constructor.newInstance("one-arg constructor");
         System.out.println(newObject);

      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

NormR1 :
• The output was a runtime error for both programs.
• Reflecting1 was in a package 'myJava', and String was just a built-in class in java.lang

JamesCherrill :
That is what I was looking for, but I am trying to understand how it works, and so I have a few questions. Below is your code, with a few minor changes:

// package myjava;

import java.lang.reflect.*;

public class Demo
{
 
   public static void main(String[] args)
   {
 
      Class<?> theClass;
      java.lang.reflect.Constructor<?> constructor;
      Object newObject;
 
      try {
 
         theClass = Class.forName("MyClass");
 
         constructor = theClass.getConstructor(); // default constructor
         newObject = constructor.newInstance();
         System.out.println(newObject);
 
         constructor = theClass.getConstructor(String.class);
         newObject = constructor.newInstance("one-arg constructor");
         System.out.println(newObject);
 
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

class MyClass {
 
   private String name;
 
   public MyClass() {
      name = "foobar";
   }
 
   public MyClass(String name) {
      this.name = name;
   }
 
   @Override
   public String toString() {
      return "An instance of MyClass " + name;
   }
}

1. Why can I not add a package statement to the beginning?
2. You used:
' Class<?> theClass;
java.lang.reflect.Constructor<?> constructor'
why can you not just import java.lang.reflect and use
' Class<?> theClass;
Constructor<?> constructor; '
3. class MyClass is written at the end of 'Demo.java', and that works fine. However, when I try to move MyClass to a new file, 'MyClass.java' (in the same directory as 'Demo.java') and make it a public class, it does not work.. what am I doing wrong?

Answers:
1. You can, if you want. Just make sure your files are in a directory structure that matches the package structure.
2. No particular reason, you can do it either way. I tend to use import for multiple references, but a fully qualified name if I use it just once.
3. I don't know what you're doing wrong there. It should work just the same with a public class in another file. Maybe something to do with your use of packages???

A quick after-thought...
if the class you want to instantiate is in a package you need the fully-qualified name of the class in your Class.forName(...), eg Class.forName("javax.swing.JLabel"). import won't help because the name is resolved at runtime.

import java.io.*;
import java.util.*;
import java.lang.reflect.*;

public class myProgram
{
  public myProgram()
  {    
    // print greeting statement
    System.out.println("Hello " + System.getProperty("user.name") + ".");
     
      String command = getInput();
      execute(command);
      System.out.println(""); // a blank line as a spacer
    
    
  }
  
  public String getInput()
  {
     String input = "";
     System.out.print("> ");
     BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
     
     try
     {
        input = reader.readLine();
           
     } catch (Exception e) {}
     
     return input;
  }

 private void execute(String input)
  {
    String arg = input;
    
     Class<?> theClass;
     Constructor<?> constructor;
     Object newObject;
    
      try {
         theClass = Class.forName(arg);
 
         constructor = theClass.getConstructor();
         newObject = constructor.newInstance();
 
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
 
 public static void main(String[] Args)
 {
   new myProgram(); 
 }

}

class Exit
{
  public Exit()
  {
    System.out.println("Hello World!");
  }
}

input:
Exit

output:
Hello World!

ok, this works. (yay) but, a few questions..
1. if I have the default class "Exit" implementing any interfaces, they do not work.. why? Can I implement an interface?
2. If I try to write 'Exit' as a public rather than default class in it's own file and then just import it, this does not work... how what directory structure or other thing(s) will fix this?
3. (I think the answer to this question will answer all of the questions) In your 'afterthought' you said that I was having some problems because of my use of packages... I currently have 'myProgram' and 'Exit' in a folder that I added to my classpath... is that not how to do this?

this does not work...

Please post the errors and the code that causes them.

those were more broad questions, they do not have specific errors that they cause.

But here is a new question:
When I write

package repository.myProgram

in the beginning of the above code, (which does work in like, any other case) I get the following error:
java.lang.ClassNotFoundException
at edu.rice.cs.plt.reflect.PathClassLoader.findClass(PathClassLoader.java:148)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

and a lot more of the same kind of message... what is happening to cause this? '~/repository' is on my classpath, and I havent had a problem with it before.. help?

ava.lang.ClassNotFoundException

What is the full name of the class not found? That should be printed out so you can see it easily.

Where is the class file and what package is it in and where is the classpath pointing when the program is executed?

Folder structure must match complete package name, so

package repository.myProgram
public class MyClass

means the classpath must contain
repository/myProgram/MyClass.class

No updates for 2 days... is this "Solved" now?

no, not solved sry, my computer crashed X/

anyway, I start with the lines:

package repository.myProgram;

import repository.myProgram.commands.*;

also, the CLASSPATH does contain ~/repository

and ~/repository contains ~/repository/myProgram/myClass

Should I have ~/repository/myProgram/commands on the PATH (and/or the CLASSPATH) to make the classes contained be reflectable?

The PATH is used by the OS to find commands like javac and java. You only set this once when the location of a command changes and the OS needs to find it.

The CLASSPATH is used by javac and java to find the definitions for classes. This needs to be set every time you execute java or javac so they can find class definitions.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.