Get the Class Name of a Field from reflection - java

Im going round in circles on this.
I have a class Person, eg
public class Person {
String name = "";
}
Now, I would like to introspect this class instance & figure out what Class is name declared as.
So, name = String or java.lang.String
This is my Code:
'this' is an instance of Person.
try {
String className = this.getClass().getName();
Class cls = Class.forName(className);
Field fieldlist[] = cls.getDeclaredFields();
for (int i = 0; i < fieldlist.length; i++) {
Field fld = fieldlist[i];
int mod = fld.getModifiers();
System.out.println("1. " + fld.toGenericString());
System.out.println("2. " + fld.getName());
System.out.println("3. " + fld.getGenericType() + "]");
Object oj = fld.getType();
// Says that 4: class java.lang.String
System.out.println("4: " + oj.toString());
Class c1 = oj.getClass();
// Should throw Exception
String stype = c1.getDeclaringClass().toString();
System.out.println("5. " + stype);
}
}
catch (Throwable e) {
System.err.println(e);
}
I managed to get to a part that states:
class java.lang.String
but I need it to be "java.lang.String"
Any ideas?

Try.. getType() and then getName()
fld.getType().getName()
Edit:(Aften Green Days' comment) -- Note that
fld.getType().getCanonicalName() will give same output in most cases. The output is different when innerclasses are used. Here is link came from search. Depending what you need to do with classname you may choose one of getName() or getCanonicalName()

System.out.println("3. " + fld.getType().getCanonicalName());
results in:
3. java.lang.String

I guess I solved it,
Should have done this:
String stype = fld.getType().getName();

I got the class name of a field by calling this
f.getDeclaringClass().getSimpleName()

Related

Serialize all properties to YAML as lowercase

So I have the following object:
public class Foo {
private String firstName = "John";
private String lastName = "Doe";
}
I want to serialize this class to YAML using SnakeYAML (not Jackson or using annotations) and make all properties lowercase like so:
firstname: John
lastname: Doe
I need to do this for a lot of classes, so I am looking for a generic way. Overriding PropertyUtils does not seem to work like in this case for parsing: How to parse field name with dash in snakeyaml?
Not entirely sure if I understood your question correctly, but here is my solution:
Sample sample = new Sample(); // your class
for(Field field : sample.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object value = field.get(sample);
System.out.println(field.getName().toLowerCase() + " " + value.toString() + " " + field.getGenericType().getTypeName());
}
for example, if you have a class like this:
public class Sample {
String name = "John";
String lastName = "Doe";
int six = 6;
}
it will generate the following output:
name John java.lang.String
lastname Doe java.lang.String
six 6 int
you can then plug this into your YAML writer
Hope that answers it

How can i return multiple getters from my method?

I have made a method that is requesting a column from my MySQL database. Fortunately this is working, but i am trying to acces the return value. Because i want to acces the getters and setters for Voedingsmiddel. A new Voedingsmiddel is created inside the method and later returned. The values of the database are assigned as the attributes of the voedingsmiddel. This method is created in my Database class and i am trying to acces it within another class.
If i am trying to acces voedingsmiddel outside of the method, it is nog giving me an object, instead it is giving me the datalocation Voedingsmiddel#6f7fd0e6.
I was able to get some of the result i am trying to get. I achieved it by changing public Voedingsmiddel getVoedingsmiddelBijId to public double getVoedingsmiddelBijId. I also changed return voedingsmiddel; into voedingsmiddel.getCalorieen; So i was able to get 1 of the getters.
By calling the method Database.getVoedingsmiddelBijId(int).getCalorieen();
Intellij is telling me the following (Result of'Voedingsmiddel.getCalorieen()' is ignored).
public Voedingsmiddel getVoedingsmiddelBijId(int idVoedingsmiddel) {
Voedingsmiddel voedingsmiddel = new Voedingsmiddel("", 0, 0,0,0,0);
try {
String query = "select * from voedingsmiddel where idVoedingsmiddel = ?";
PreparedStatement preparedStatement = myCon.prepareStatement(query);
preparedStatement.setInt(1, idVoedingsmiddel);
myRes = preparedStatement.executeQuery();
while (myRes.next()) {
int idvoedingsmiddel = myRes.getInt("idVoedingsmiddel");
String naam = myRes.getString("naam");
int gram = myRes.getInt("gram");
double calorieen = myRes.getDouble("calorieën");
double koolhydraten = myRes.getDouble("koolhydraten");
double eiwitten = myRes.getDouble("eiwitten");
double vetten = myRes.getDouble("vetten");
voedingsmiddel = new Voedingsmiddel(naam, gram, calorieen, koolhydraten, eiwitten, vetten);
System.out.println("idVoedingsmiddel " + idvoedingsmiddel + " naam " + naam + " gram " + gram + " calorieën " + calorieen + " koolhydraten " + koolhydraten + " eiwitten " + eiwitten + " vetten " + vetten);
}
} catch (Exception exc) {
exc.printStackTrace();
System.out.println("Error: " + exc);
}
return voedingsmiddel;
}
First of all, i would really appreciate it, if someone could explain me what i am doing wrong. Also a solution to the problem would be more then welcome!
The expected result is that the return value of the method would be an object instead of what i think is a datalocation. So i can call the getters and setters for that object.
I have a history of posting too much code and not enough information. So i hope this is better, if not feel free to correct me.

How to pass a NumberFormat object to a method?

I'm trying to use a NumberFormat object to display a price. I'm very new to programming, my book isn't very helpful, nor is my teacher. I have a class called Product and a class called MyProduct, which is a subclass of Product. In the Product class there is a method called getPrice() that has no parameters. All it does is return the value for price. My task is to create a method in MyProduct called getPrice(NumberFormat nf) that returns the price, but formatted as currency. In the main method, if I use myproduct.getPrice(); I get the price, but unformatted (I know this is because it's calling getPrice() from Product, not getPrice(NumberFormat nf) from MyProduct. My question is what do I put in as an argument to stop getting a compile time error? I've tried getPrice(nf), getPrice(this), getPrice(price), just about anything I can think of and nothing works. Any help would be greatly appreciated and all relevant lines of code are posted below. Thanks in advance.
Below is the MyProduct class
public class MyProduct extends Product{
public MyProduct()
{
super();
}
NumberFormat nf;
public String getPrice(NumberFormat nf) {
this.nf = NumberFormat.getCurrencyInstance();
String priceFormatted = nf.format(price);
return priceFormatted;
}
And here is ProductApp class
public class ProductApp {
public static void main(String args[]) {
// display a welcome message
System.out.println("Welcome to the Product Viewer");
System.out.println();
// create 1 or more line items
Scanner sc = new Scanner(System.in);
String choice = "y";
while (choice.equalsIgnoreCase("y")) {
// get input from user
System.out.print("Enter product code: ");
String productCode = sc.nextLine();
// Use a ProductReader object to get the Product object
ProductDB db = new ProductDB();
MyProduct myproduct = db.getProduct(productCode);
// display the output
String message = "\nPRODUCT\n" +
"Code: " + myproduct.getCode() + "\n" +
"Description: " + myproduct.getDescription() + "\n" +
"Price: " + myproduct.getPrice()+ "\n";
System.out.println(message);
// see if the user wants to continue
System.out.print("Continue? (y/n): ");
choice = sc.nextLine();
System.out.println();
}
System.out.println("Bye!");
The line I need help with is
"Price: " + myproduct.getPrice()+ "\n";
As you are instantiating nf within your getPrice method then I would not bother passing it. Maybe change the method name to something like getPriceAsString defined as
public String getPriceAsString() {
NumberFormat nf = NumberFormat.getCurrencyInstance(); // keep local
String priceFormatted = nf.format(price);
return priceFormatted;
}
Then you can call it as myProduct.getPriceAsString ()
edit
As per you comment
In main do
"Price: " + myproduct.getPrice(NumberFormat.getCurrencyInstance())+ "\n";
And declare the method as
public String getPrice(NumberFormat nf) {
return nf.format(price);
}
I assume that price is correctly set

Parsing a multiline file

Ive to parse a multiline file, structured as follows:
Name Surname
birthdate(int)
Name Surname
birthdate(int)
and so on. I opened the file, getting an ArrayList, and created a class which serves as a data structure, but i don't know how to parse each string, recognising if it is a number or a name. Can you help me?
You can use java.util.Scanner class to read your file
It has helper methods to read various types of input if you know the structure of input data (I assume you know its structure)
Here is a sample code to help you read it from some file with given structure
Scanner s = new Scanner(new File("input.txt"));
while(s.hasNext()) {
System.out.println("First Name : " + s.next() + ", Last Name : " + s.next() + ", Age : " +s.nextInt());
}
s.close();
You can create a class with attributes firstName, lastName and age and assign above values to a new object and add that object in List.
Hope this helps.
I guess, this is the main concern:
i don't know how to parse each string, recognising if it is a number
or a name.
Use isNumeric() function to see if you can parse value to number or leave it as a string. Then parse it accordind to value the function returns.
public static boolean isNumeric(String str) {
try {
double d = Double.parseDouble(str);
} catch(NumberFormatException nfe) {
return false;
}
return true;
}
...
//put data into ArrayList
for (int i = 0; i < data.size(); i++) {
String elem = data.get(i);
boolean isNum = isNumeric(elem);
if (isNum) {
int val = Integer.parseInt(elem);
} else {
//do what you want with `elem`
}
}

Why can't I use a getAnnotation() on a reference of Annotation?

We can use getAnnotations() on an interface of Annotation but not getAnnotation? Why
When I changed the interface from MyAnno to Annotation in the followng program, the compiler was not recognizing the data defined in the Annotation like the str() etc...
package british_by_blood;
import java.lang.annotation.*;
import java.lang.reflect.*;
#Retention (RetentionPolicy.RUNTIME)
#interface Hashingsnr {
String str();
int yuiop();
double fdfd();
}
public class German_by_Descent {
#Hashingsnr(str = "Annotation Example", yuiop = 100, fdfd = 4.267)
public void mymeth(){
German_by_Descent ob = new German_by_Descent();
try{
Class c = ob.getClass();
Method m = c.getMethod("mymeth");
Hashingsnr anno = m.getAnnotation(Hashingsnr.class);
System.out.println(anno.str() + " " + anno.yuiop() + " " + anno.fdfd());
}catch(NoSuchMethodException exc){
System.out.println("Method Not Found");
}
}
public static void main(String[] args) {
German_by_Descent ogb = new German_by_Descent();
ogb.mymeth();
}
}
As far as I understand, you want to change this line
Hashingsnr anno = m.getAnnotation(Hashingsnr.class);
to
Annotation anno = m.getAnnotation(Hashingsnr.class);
Of course, now anno is of type java.lang.annotation.Annotation and that interface does not define your methods str(), yuiop() and fdfd(). That's why the compiler complains in the following line.
Like with ordinary java types, you'll have to cast back to the real annotation:
System.out.println(
((Hashingsnr) anno).str() + " " +
((Hashingsnr) anno).yuiop() + " " +
((Hashingsnr) anno).fdfd());
Your program seems to be working correctly. I get the following output when i run it...
run-single:
Annotation Example 100 4.267
BUILD SUCCESSFUL (total time: 12 seconds)
I'm i missing something in your question?
I also changed the code to use the getAnnotations() method and recieved the same result...
final Annotation[] annos = m.getAnnotations();
for (Annotation anno : annos) {
if (anno instanceof Hashingsnr) {
final Hashingsnr impl = (Hashingsnr)anno;
System.out.println(impl.str() + " " + impl.yuiop() + " " + impl.fdfd());
}
}

Categories