Java equivalent of python's getattr? - java

I'm converting some python code to java, and have a situation where I need to call methods of an object but don't know which methods until runtime. In python I resolve this by using getattr on my object and passing it a string that is the name of my method. How would you do something similar in Java?

Class.getField is your friend. It probably won't be very straightforward though since Python is dynamically typed and Java is statically typed (unless you know the types of your fields in advance.)
EDIT: How to translate these examples. http://effbot.org/zone/python-getattr.htm
Attribute Lookup
Python
//normal
value = obj.attribute
//runtime
value = getattr(obj, "attribute")
Java
//normal
value = obj.attribute;
//runtime
value = obj.getClass().getField("attribute").get(obj);
Method Call
Python
//normal
result = obj.method(args)
//runtime
func = getattr(obj, "method")
result = func(args)
Java
//normal
result = obj.method(args);
//runtime
Method func = obj.getClass().getMethod("method", Object[].class);
result = func.invoke(obj, args);
In the simpler cases, you need to know whether you have a field or a method. esp as they can have the same name. Additionally methods can be overloaded, so you need to know which method signature you want.
If you don't care which method or field you get, you can implement this as a helper method fairly easily.

You can start here to learn about Java Reflection.

You can use java reflection but there is no exact equivalent of getattr.

In Java you do this with the Reflection API (and it's usually pretty cumbersome).
MethodUtils in Apache Commons BeanUtils project may make it a bit easier to work with, though it's a pretty hefty dependency for something simple like this.

You should use the Reflection API. Since the pure API is a bit ... unapproachable, you should have a look at helpers like commons beanutils or reflections.

The easiest way to handle this is to create a Map object in Java class & keep adding the name value pairs & retrieve it accordingly though it might not support different types that setAttr supports.

Related

One or many argument in Scala [duplicate]

Why do all scala vararg methods, when used from java, seem to accept a Seq of variables, and can't be used as java native vararg methods. Is this a bug?
For instance, Buffer has method def append(elems: A*): Unit. But in java it has another signature: void append(Seq<A>).
If you control the scala code you can use #varargs to make it generate a java-compatible varags method, e.g. #varargs def append(elems: A*): Unit = {}
It is not a bug. It is a design choice that favors vararg use within Scala over interoperability with Java. For example, it allows you to pass a List into a Scala varargs method without having to convert it to an Array on the way.
If you need to use Scala varargs from Java, you should create some scala Seq instead. You can, for example, write a Java wrapper to get an array automatically created, and then use the genericWrapArray method from the Predef object.
you can easily cast a Seq in varargs using :_*. For example :
val b = collection.mutable.ListBuffer.empty[Int]
b.append(List(1, 2):_*)
so this avoid code duplication in the collection API.
You can also simply use appendAll :
b.appendAll((List(1, 2))

Get delegate function for arbitrary java method

Is there an easy way to get an arbitrary Function version of a method on a POJO?
For example:
FluentIterable.from(myCollection).uniqueIndex(Functions.for(Item.class).getId)
.first(Predicates.equalTo(id)).get();
Where Functions.for ideally behaves like Mockito.mock
Actually you can use lambdaj which is
a library that makes easier to address this issue by allowing to
manipulate collections in a pseudo-functional and statically typed
way.
Lambdaj does similar tricks as Mockito, so you should read its limitations (most important is that your POJO must not be final).
With lambdaj, your code could be something like this (note that uniqueIndex from your example returns Map, which does not have first method, so I'll guess here):
import ch.lambdaj.Lambda.*; // for all static methods used below
// just items indexed by their ids
Map<Intgeger, Item> indexed = index(myCollection, on(Item.class).getId());
// or more likely you want
Item foundItem = selectFirst(
myCollection, having(on(Item.class).getId(), equalTo(id)));
That's not how Java works.
However, with Java 8, you can use a method reference to create a lambda:
FluentIterable.from(myCollection).uniqueIndex(Item::getId)
.first(Predicates.equalTo(id)).get();

Using scala object inside java?

In my java code, I am calling a method, from a class which is defined in Scala, and I want to use one of its methods in java. Here is how I call it and it works fine.
Seq<SomeObjectType> variableName = ScalaClass.MethodInTheScalaClass();
I can call this function in java in this form, but since I am calling this method from a compiled package, I can't see what it going on (and therefore I can't change it).
The problem now is that, I don't know how to iterate over the "variableName" in java (since Seq is a scala type).
How can I iterate over variableName or convert it to a Java object (e.g. List)?
Try this:
java.util.List<SomeObjectType> res =
scala.collection.JavaConverters$.MODULE$.seqAsJavaListConverter(variableName).asJava();
You could get converters list in JavaConverters documentation.
You should use JavaConverters$.MODULE$ to get JavaConverters object from Java.

Java Interface Reflection Alternatives

I am developing an application that makes use of the Java Interface as more than a Java interface, i.e., During runtime, the user should be able to list the available methods within the interface class, which may be anything:
private Class<? extends BaseInterface> interfaceClass.
At runtime, I would like to enum the available methods, and then based on what the user chooses, invoke some method.
My question is: Does the Java "Interface" architecture provide any method for me to peek and invoke methods without using the Reflection API?
I wish there were something like this (Maybe there is):
private Interface<? extends BaseInterface> interfaceAPI;
public void someMethod(){
interfaceAPI.listMethods();
interfaceAPI.getAnnotations();
}
Maybe there is some way to use Type Generics to accomplish what I want?
Thanks,
Phaedrus
This is exactly what Reflection was built for.
Take a look at Apache Commons BeanUtils. It's an excellent library for programmatically discovering an object's methods and properties easily (i.e. without writing low-level reflection code). I've used it on several projects. It also provides an easier API for accessing those object members once they're discovered. PropertyUtils and MethodUtils are good places to start.
My question is: Does the Java "Interface" architecture provide any method for me to peek and invoke methods without using the Reflection API?
a) No, reflection is the only way to do that
b) don't do that at all. If you want a dynamic language, use Groovy. It's syntax is (can be) almost identical to java, but it has most of this functionality built in already. (Many other languages will also work, but Groovy is closest to Java when comparing the syntax)
Reflection is the only way to list methods of an arbitrary object. Well, parsing the bytecode also works, but it's tedious.
Unfortunately it looks like reflection is the only way to go. Unfortunate because reflection is not only slower but programming and maintaining is a hassle. So I suggest you use apache bean util library. (specifically methodutils.)
Although there's no way around reflection here, it can be made relatively painless if you use annotations to mark your callable methods. An example of this approach at work is the javax.jws annotation set for webservices. The ideas used there can be really useful, you can define a display name for each of your methods/parameters for example.
Reflection with Annotations is working Nicely
for (Method m : interfaceClass.getMethods()) {
if (m.isAnnotationPresent(UIf.class)) {
UIf x = m.getAnnotation(UIf.class);
addDefinedCommand( new CommandDef(
interfaceClass,
u,
x.name().isEmpty() ? m.getName() : x.name(),
x.description())
);
}
}

this["var"+"name"] in java

In AS3 I can write this["foo"] for access to a variable foo. I can construct any string in brackets. Is there a way to do this in Java?
You can use Java's reflection API to achieve the same effect, albeit much less elegantly. See here for a tutorial.
No, you can't do this. But you don't need to. There's an easier way to call variables. You just need to use this.foo to refer to the variable. Now, if you're trying to do something like
String var = "foo";
this[var] = "something else";
You may be able to do that with java reflection, but it would have quite a bit of overhead and I believe it would be quite inefficient.
No. If you want such kind of access, you should consider using Set interface (or reflection api, as noted before me).

Categories