the code is
Field field = st.class.getField("g_"+selectedGroup);
st is my class, and g_+"selectedgroup" is in the st class as String array
how to get that string array?
I need something: String sa[]= field.getStringArray[]; but only getInt, getBoolean there is :(
how to?
Try this,
Field field = ST.class.getField("g_"+selectedGroup);
String[] sa = (String[])field.get(stInstance);
Where stInstance is an instance of ST class.
You just use get.
field.get(instance);
If it's a static field, instance can be null (or really anything).
Related
I am retrieving a String variable from the Database and storing in a variable.
String name = "Peter" ---- >(retrieved from the database)
I already have a class called Peter. I need to initialize the class using the retrieved variable name.
Assume that ,whatever String is retrieved from the database , I have a class defined for it in my package...
Is there a way to create a Object for the String I retrieve from the Database?
Class.forName(name).newInstance()
Using Class.forName() - java.lang.reflect
If we know the name of the class & if it has a public default constructor we can create an object in this way.
Class myClass = Class.forName("MyClass");
Class[] types = {Double.TYPE, this.getClass()};
Constructor constructor = myClass.getConstructor(types);
Object[] parameters = {new Double(0), this};
Object instanceOfMyClass = constructor.newInstance(parameters);
See Java how to instantiate a class from string
Here we go, suppose if i have class Name :
class Name {
String firstName, lastName;
// getters and setters, etc.
}
and then Name class's object is declared somewhere in other class :
class Other {
Name name;
// getter and setters, etc.
}
Now if i do something like :
Other o = new Other();
Field[] fields = o.getClass().getDeclaredFields();
fields[0] --> is 'name' the Object of 'Name' class
but when i say field[0].getClass() :
It gives me java.lang.reflect.Field class object and not Name class object.
How can i get original class object from a field like 'name'
Field.getType method returns a Class object that identifies the declared type for the field represented by this Field object.
This should help
Other o = new Other();
Class<?> classTemp1 = o.getClass();
Field[] allFields = classTemp1.getDeclaredFields();
Now u can query each field for name ,type etc
fields[i].getType()
Please check
http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html#getType()
getType() Returns a Type object that represents the declared type for the field represented by this Field object.
field[0].getClass()
Will return you the Type object that represents field[0] which is obiviously field[0].
Basically, you need to ask the field for the value of a specific instance, something like
Name name = (Name)fields[0].get(o);
Now. It's pretty dangrous to do a blind cast like this, I'd be probably simply assign it to a Object first and then do instanceof or maybe use Field#getName to determine the name of the field and take action from there...
nb- I'd make mention of getType, but Evgeniy Dorofeev beat me to it and I don't want take away from his answer
Based on Evgeniy's answer, this line is what you are looking for:
String actualClassName = fields[0].getType().getName();
Let's say, I have an array of complex data type objects. For example: FullName[100]. Each FullName object has has 2 class member variables: String FirstName and String LastName. Now, from this array of FullName objects, I want to retrieve an array of String FirstNames[].
How can I do this without the extensive for loop application?
You can try to take a look at Functional Programming in Java and apply map function from one of the libraries.
I'm not sure why avoiding a loop is so important, but you could do it like this:
You could store the names in String arrays and use the Flyweight pattern for your FullName class. So your FullName instances hold a reference to these arrays, and indices that point to the correct elements in the array.
In Java 8 you can do something like this:
public class Test {
class FullName {
private String firstName;
String getFirstName(){return firstName;}
}
void main(String... argv) {
FullName names[] = {new FullName()};
String[] firstNames = Arrays.stream(names).map(FullName::getFirstName).toArray(String[]::new);
}
}
I am having trouble declaring an enumeration for DB field types that I can use across all functions of a particular class. With the following code I get "cannot resolve USERNAME to a variable type":
public class SQL_access {
public enum DBfields { BLANK, USERNAME, ID, PASSWORD, FIRSTNAME, LASTNAME };
public boolean loginValidate( String username, String password ){
String DBuser, DBpass;
PreparedStatement table = connectToTable( "firstsql", "users");
ResultSet row = table.executeQuery();;
while(row.next()){
DBuser = row.getString(USERNAME);
if(DBuser.equals(username)){
DBpass = row.getString(PASSWORD);
break;
}
}
}
};
You need to use DBfields.USERNAME.
UPDATE:
in order to use with the getString(String) method, you need to use the name of the enum, like: Dbfields.USERNAME.name().
if you are using the enums only for the jdbc API access, you would be better off just using a String constant:
public static final String DBFIELD_USERNAME = "USERNAME";
You need to reference the enum Type: DBfields.USERNAME, or statically import the enum like:
import static mypackage.SQL_access.DBfields.*;
Also, in your case, this is not enough. You need to pass the column name -- a String -- or the column position -- an int -- to the ResultSet:
row.getString(DBfields.USERNAME.name());
Used like this, you loose the main advantage of enums which is it's static nature, but it can still be useful in other places in your code if you refer to these values as a "bag".
You should access the enum by using DBfields.USERNAME.
See the Oracle Docs for more information.
Try qualifying the enumerator with the enum type:
while(row.next()){
DBuser = row.getString( DBfields.USERNAME);
if(DBuser.equals(username)){
DBpass = row.getString( DBfields.PASSWORD);
break;
}
}
When you reference an enumeration it is always in this form EnumName.Field. In your example you need the following:
DBUser = row.getString(DBfields.USERNAME);
DBpass=row.getString(DBfields.PASSWORD);
to access your enumbs use DBfields.USERNAME, but this will not help you, bacuse row.getString() needs an int as argument. Your Enumbs are of the Type DBFields not int.
better use public static final int USERNAME = the int value here; and call with row.getString(USERNAME);.
Wrong way.You need to call the enum using DBfields.PASSWORD.
You need to call like this: DBfields.PASSWORD
I have an abstract class as follows. I want to get all the values of member variables.
public abstract class PARAMS {
public static final String NAME1 = "VAL1";
public static final String NAME2 = "VAL2";
public static final String NAME3 = "VAL3";
}
The values are retrieved using reflection as follows.
Field[] fields = PARAMS.class.getFields();
for (Field field : fields) {
String name = field.getName() ;
String value = (String) field.get(name);
}
This is the first time I am experimenting with reflection. Is this a correct way to achieve the goal? I would like to know what are the pitfalls in using reflection in this case.
You code iterates over both static and private fields. So you should check that you iterate over static fields only.
for (Field field : PARAMS.class.getFields()) {
if (Modifiered.isStatic(field.getModifiers())) continue;
String name = field.getName() ;
String value = (String) field.get(PARAMS.class);
}
NB: as Jon mentioned, for static field access the instance parameter is ignored. However, I prefer passing in the class instead of null since this is a better documentation of the indent.
It is however even better practice to annotate your fields with an annotation so that you only get those fields that you really want no other static fields added by other programmers (or even the Java language behind the scenes). If you do so, your code would look like
for (Field field : PARAMS.class.getFields()) {
if (!field.isAnnotationsPresent(YourAnnotation.class)) continue;
String name = field.getName() ;
String value = (String) field.get(PARAMS.class);
}
It's not quite correct - the argument to get should ideally be null for the sake of readability: the point of that argument is to give it a target for when you're retrieving instance fields.
So your code can be just:
Field[] fields = PARAMS.class.getFields();
for (Field field : fields) {
String name = field.getName() ;
String value = (String) field.get(null);
}
Now, this should work... but what are you going to do with these values? Is there any reason why you want to do this rather than creating an immutable Map<String, String> which is exposed directly?
Reflection is fine where it's necessary, but you haven't given enough information to determine whether it's actually necessary in this case.
another problem, getFields return all accessible fields (static or not) of this class and all its superclasses. Not a problem for the specific code you posted, since the only superclass is Object which has no public field.
I would at least test if the field is declared in the correct class - getDeclaringClass() - and if it has the correct return type - getType().
Using an Annotation, as Adrian suggested, is best IMHO.