Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

variable names 2

Status
Not open for further replies.

Adkron

Programmer
Jun 6, 2005
39
US
Does anyone know of a way to get the names of variables from a bean. I want to write a class that creates spreadsheets from database queries, but I don't want to have to write it for each bean/table. I want to be able to pass in a list of beans and then do something like:

variables.getListVariableNames();
cell.setValue(variables.name());
cell.setValue(variables.name().getValue());

Am I just going to have to write some enums for each bean. If so can I do:

class.getValue(enumValue[0]);

if the enumValue[0] evaluates to lets say blah which is the name of a variable in class.

and have the enumValue be interpreted as the variable.

Amos
Computer Science
U of MO - Rolla
 
Have a look in the Java API docs at the classes in the java.lang.reflect package.

Tim
 
Thanks I will take a look.

Amos
Computer Science
U of MO - Rolla
 
I'm trying to use reflection like this

methods.invoke( localObjects[position], null )

I run it through my debugger and it errors with a null pointer exception. So I read and find that the method is an instance. Here is the mthod it is trying to invoke.

public String getAddress() {
return address;
}

Can anyone tell me what I can do to invoke this method?

Amos
Computer Science
U of MO - Rolla
 
You have to locate the method first. Use the getMethod method of the class your introspecting to do this (look at the java.lang.Class API). I'm assuming that this is where your null pointer is coming from.

Maybe if you post the complete relevant code.

Tim
 
I think it is because I used
Hashmap[] map = null;
map = new HashMap[10];

but I didn't do map[1] = new HashMap();

Amos
Computer Science
U of MO - Rolla
 
Code:
Hashmap[] map = null;
map = new HashMap[10];
... declares and creates a new array to hold HashMap instances. The array will initially be full of nulls.

Code:
map[1] = new HashMap();
... Creates a new HashMap instance and puts it into the second element of the array (Java's arrays are 0 subscript based).

By the way, the first bit of code above can be done more efficiently in one line...
Code:
Hashmap[] map = new HashMap[10];

I don't see how any of this relates directly to your original problem, though, without seeing the code you are using. Please post it.

Tim
 
I hope the compiler detect the two lines and put the tim, bytecode just in one :)

In the other side, I agree with you, there's info missing in this puzzle. I don't think a HashMap has a method called getAddress().

An example of invoking methods:
But remember that reflection should be the last option to call a method: it's hard to code, read and maintain, and it's slower than "traditional" execution.

Cheers,
Dian
 
Thanks for that Dian. I don't have a deep knowledge of the Java compiler optimisations and I accept your comment. Though putting it on one line and not relying on the optimiser does save typing, of course :)

Your points about reflection are well made and Adkron should consider them. And Adkron, please give us as much info regarding your issues if you want us to help you better. We don't generally like to have to dig, dig, dig for scraps of info about your problems. Help us to help you.

Tim
 
The compiler does a lot of stuff behind the scenes.

For example, if you wrote :

Code:
public void someMethod(int max) {
   for (int i = 0; i < max; i++) {
      String s = "hello" +i;
      System.out.println(s);
   }
}

I expect it would end up the same, in byte code, as writing :


Code:
public void someMethod(int max) {
   String s;
   for (int i = 0; i < max; i++) {
      s = "hello" +i;
      System.out.println(s); 
   }
}


--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
I just said "I hope". But I've done some tests and you were rigth: there's a difference between both cases, at least with Sun's 1.4 compiler.

I know it's a little off-topic, but I'll show you the results: I've tried both cases, compiled and used javap to find out the bytecode instructions

Compiler.java
Code:
import java.util.HashMap;

public class Compiler 
{
	public static void main(String[] args) 
	{
	HashMap h = new HashMap();
	}
}

Results from javap Compiler

Code:
Compiled from "Compiler.java"
public class Compiler extends java.lang.Object{
public Compiler();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new     #2; //class HashMap
   3:   dup
   4:   invokespecial   #3; //Method java/util/HashMap."<init>":()V
   7:   astore_1
   8:   return

}

Compiler.java
Code:
import java.util.HashMap;

public class Compiler 
{
	public static void main(String[] args) 
	{
	HashMap h = null;
	h= new HashMap();
	}
}

Results from javap Compiler

Code:
Compiled from "Compiler.java"
public class Compiler extends java.lang.Object{
public Compiler();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   aconst_null
   1:   astore_1
   2:   new     #2; //class HashMap
   5:   dup
   6:   invokespecial   #3; //Method java/util/HashMap."<init>":()V
   9:   astore_1
   10:  return

}

Curious, isn't it?

Cheers,
Dian
 
Well that's the thing, sedj. I recall, no so long ago, running a profiler on some code and as a result I manually made a change exactly like the one you suggest which did speed up the code, implying the compiler didn't make this optimisation. However, that was with JDK1.4 and I'm willing to accept that 1.5 (and the upcoming 1.6) introduce more / better optimisations.

Tim
 
Humm, I answered without reading sedj's post.

I wouldn't expect that to work that way. I guess if the object is declared outside the loop, it will be created in each iteration.

Cheers,
Dian
 
Interesting points - in that case java's compiler aint so good as I thought !

(Note : perhaps String is a bad example - just think an object allocated on the heap)

In my mind, the compiler really should realise that because the object is declared in the loop, it need not actually malloc a new object onto the heap, but all it needs to do is realloc that same pointer's memory - rather than creating different pointers for each allocation.

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
Looks like we've trusted too much the compiler. Here we have a complete explanation on what's going on behind the scenes with allocated objects:
I guess a C compiler would have done the job, maybe I'm wrong.

Btw, Adkron, don't get frightened by all this almost useless stuff, you still can post more details to your question.

Cheers,
Dian
 
[bigsmile]Adkron, see what happens when you don't give us enough info. We start waffling and hijack your post.[wink]

Tim
 
Thanks I got it all figured out. Sorry that I didn't give enough info about the hasmap thing. I was just saying that I had made the new array but I for got to create the individual hashmaps in that array. I know that it starts at zero and it is in a loop. If you want I will post my code for everyone so that they can see my solution. If you have any ideas on speeding it up you can let me know. I just got a new computer at work so I have to set up my enviroment before I can post the code.

Amos
Computer Science
U of MO - Rolla
 
//constructor
public CreateExcelSheet( List passedClasses ) {
//create a hash map for each bean
map = new HashMap[passedClasses.size()];
localObjects = new Object[passedClasses.size()];
localClass = passedClasses.get(0).getClass();
for ( int i = 0; i < passedClasses.size(); i ++ ) {
localObjects = passedClasses.get(i);
map = new HashMap();
createHash(i);
}
}

// Creates a hash using column names as the key and value as the
private void createHash( int position ) {

Method[] methods = localClass.getMethods();
String methodName = null;
Object methodValue = null;

for ( int i = 0; i < methods.length; i++ ) {
try {
methodName = methods.getName();
if ( methodName.startsWith( "get" ) ) {
methodValue = methods.invoke( localObjects[position], null );
if ( methodValue != null ){
map[position].put( parseMethodName( methodName ), methodValue );
}
}
} catch ( Exception e) {
// TODO add error message
e.printStackTrace();
}
}

keys = (String[]) map[position].keySet().toArray();
}


private Object parseMethodName(String methodName) {
String variableName = methodName.substring(3, methodName.length() );
return variableName;
}

Amos
Programer/Analyst
United States Postal Service
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top