Reflection in Java is a powerful tool, expecially useful when your code must get in touch with the outer world (configuration files, database, http protocol...). Here's an example, a simple parser for a CSV string where every value has a tag:
id=1112396889697; t=22740834120; x=184549969; y=8389273; f=89; q0=0.18810; q1=0.07500; q2=-0.23573; q3=0.96616
What I would like to do here is parsing the data into an object with (a subset of) the fields in each line. The solution is overly simplified, but it just works:
import java.lang.reflect.Field;
public class Sample
{
class SampleData
{
public Long t = new Long(0);
public Long x = new Long(0);
public Long y = new Long(0);
public Long f = new Long(0);
public Double q0 = new Double(0);
public Double q1 = new Double(0);
public Double q2 = new Double(0);
public Double q3 = new Double(0);
}
private SampleData data = new SampleData();
public Sample(String taggedCsv)
{
if (taggedCsv != null && !"".equals(taggedCsv))
{
String[] chunks = taggedCsv.split(";");
for (String chunk : chunks)
{
chunk = chunk.trim();
String[] parts = chunk.split("=");
String tag = parts[0].trim();
String value = parts[1].trim();
try
{
Class<? extends SampleData> class1 = data.getClass();
Field f = class1.getField(tag);
if (f!=null)
{
if (f.getType().equals(java.lang.Double.class))
{
f.set(data, new Double(value));
}
else
if (f.getType().equals(java.lang.Long.class))
{
f.set(data, new Long(value));
}
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
}
public long getT()
{
return data.t.longValue();
}
public double getX()
{
return data.x.longValue();
}
public double getY()
{
return data.y.longValue();
}
public double getF()
{
return data.f.longValue();
}
public double getQ0()
{
return data.q0.doubleValue();
}
public double getQ1()
{
return data.q1.doubleValue();
}
public double getQ2()
{
return data.q2.doubleValue();
}
public double getQ3()
{
return data.q3.doubleValue();
}
}
It seems like it's doing its job just fine:
@Test
public void firstTest()
{
Sample a = new Sample(
"id=1112396889697; t=22740834120; " +
"x=184549969; y=8389273; f=89; " +
"q0=0.18810; q1=0.07500; q2=-0.23573; q3=0.96616");
assertTrue(22740834120L==a.getT());
assertTrue(184549969L==a.getX());
assertTrue(8389273L==a.getY());
}
NOTE: there is an awkward thing in the code up there. To obtain encapsulation I had to use a PRIVATE class (DataSample) with PUBLIC fields because getField() can not access PRIVATE fields. There are other ways round, but they are not as lean. Still don't like it, though.
0 commenti:
Posta un commento