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).
Related
I am coming from PHP to Java and I have some questions about "dynamic" functions.
Kinda like in php where you can do an include(VARNAME.".php"); and if varname is a it'll include a.php if its x it'll include x.php.
I wanna do that in Java but with functions.
Kinda like I have a varname and I want to include a function. So if varname is Test it'll include test() but I have a bunch of functions and its a nuisance to do
if(varname == "x"){ x(); }.
Is there any easy way to do it?
First off, if(varname == "x") is surely not what you want. This is a common Java mistake and will check the object identity, not the object value. You want if(varname.equals("x")).
Second, this isn't very idiomatic Java. As Jason pointed out, you can use reflection to do a dynamic method look-up. However, there is almost certainly a better design for what you are trying to accomplish.
Java is a very different language from PHP. Trying to apply PHP idioms to Java will only cause you pain and suffering.
Having said all that, I think this is roughly the code you are looking for:
Method method = this.class.getDeclaredMethod("x", new Class[] {});
method.invoke(this, new Object[] {});
If your varname equates to a function on the class you are in, you could theoretically use reflection to accomplish this. See this article from Sun/Oracle for more details
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.
I often find myself writing code like this:
throwExceptionWhenEmpty(fileType, "fileType");
throwExceptionWhenEmpty(channel, "channel");
throwExceptionWhenEmpty(url, "url");
The throwExceptionWhenEmpty method does something like this:
private void throwExceptionWhenEmpty(final String var, final String varName) {
if (var == null || var.isEmpty()) {
throw new RuntimeException("Parameter " + varName + " may not be null or empty.");
}
}
I'd like to avoid this obvious redundancy passing the variable name as string. Is there a way the java compiler can insert the variable name in the string for me?
I'd be happy if I could write something like this:
throwExceptionWhenEmpty(fileType, nameOf(fileType));
That should answer your question: SO: How to get name of a variable.
It's not (easily) possible in Java.
You could use a preprocessor and integrate it in your build process. That would probably be very simple and portable. But as Stephen C said in the comments section, that's really not the Java way and is therefore not recommended.
No, Java cannot do this until it starts supporting closures which make fields (and methods) first class citizens of the programming language.
See http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc for an overview on one of the proposals, in which you could do what you want using #field syntax.
Variable names are lost when the code is compiled so unless Reflection provides access to them (and even then) I'm pretty sure it's impossible. Sorry.
Java doesn't really have a way to do this but you can get some help from your IDE (if you are using one). In Eclipse you can create a template like this that could help:
throwExceptionWhenEmpty(${varname}, "${varname}");
${cursor}
You could do something like (I might be misunderstanding what you want to do)
var.getClass().getName()
Where Var is your Object passed into the method as an Object.
As the question says, what are some common/major issues that C++ programmers face when switching to Java? I am looking for some broad topic names or examples and day to day adjustments that engineers had to make. I can then go and do an in-depth reading on this.
I am specifically interested in opinions of engineers who have worked in C++ for years and had to work with Java but any pointers from others or even book recommendations are more than welcome.
In C++ you'd use destructors to clean up file descriptors, database connections and the like. The naive equivalent is to use finalizers. Don't. Ever.
Instead use this pattern:
OutputStream os;
try {
os = ...
// do stuff
} finally {
try { os.close(); } catch (Exception e) { }
}
You'll end up doing stuff like that a lot.
If you specify no access modifer, in Java the members are package-private by default, unlike C++ in which they are private. Package-private is an annoying access level meaning it's private but anything in the same package can access it too (which is an idiotic default access level imho);
There is no stack/heap separation. Everything is created on the heap (well, that's not strictly true but we'll pretend it is);
There is no pass-by-reference;
The equivalent to function pointers is anonymous interfaces.
My biggest hurdle crossing from C++ to Java was ditching procedural code. I was very used to tying all my objects together within procedures. Without procedural code in java, I made circular references everywhere. I had to learn how to call objects from objects without them being dependents of each other. It was the Biggest hurdle but the easiest to overcome.
Number 2 personal issue is documentation. JavaDoc is useful but to many java projects are under the misconception that all that is needed is the JavaDoc. I saw much better documentation in C++ projects. This may just be a personal preference for documentation outside of the code.
Number 3. There are in fact pointers in java, just no pointer arithmetic. In java they are called references. Don't think that you can ignore where things are pointing at, it will come back with a big bite.
== and .equals are not equal.
== will look at the pointer(reference) while .equals will look at the value that the reference is pointing at.
Generics (instead of templates), specifically the way they were implemented using type erasure.
Since you mention book recommendations, definitely read Effective Java, 2nd ed.—it addresses most of the pitfalls I've seen listed in the answers.
Creating a reference by accident when one was thinking of a copy constructor:
myClass me = new myClass();
myClass somebodyElse = me; /* A reference, not a value copied into an independent instance! */
somebodyElse.setPhoneNumber(5551234);
/* Hey... how come my phone doesn't work anymore?!?!? */
No multiple inheritance, and every class implicitly derives from java.lang.Object (which has a number of important methods you definitely have to know and understand)
You can have a sort of multiple inheritance by implementing interfaces
No operator overloading except for '+' (for Strings), and definitely none you can do yourself
No unsigned numerical types, except char, which shouldn't really be used as a numerical type. If you have to deal with unsigned types, you have to do a lot of casting and masking.
Strings are not null-terminated, instead they are based on char arrays and as such are immutable. As a consequence of this, building a long String by appending with += in a loop is O(n^2), so don't do it; use a StringBuilder instead.
Getting used to having a garbage collector. Not being able to rely on a destructor to clean up resources that the GC does not handle.
Everything is passed by value, because references are passed instead of objects.
No copy constructor, unless you have a need to clone. No assignment operator.
All methods are virtual by default, which is the opposite of C++.
Explicit language support for interfaces - pure virtual classes in C++.
It's all the little bitty syntax differences that got me. Lack of destructors.
On the other hand, being able to write a main for each class (immensely handy or testing) is real nice; after you get used to it, the structure and tricks available with jar files are real nice; the fact that the semantics are completely defined (eg, int is the same everywhere) is real nice.
My worst problem was keeping in mind the ownership of memory at all times. In C++, it's a necessary thing to do, and it creates some patterns in developer's mind that are hard to overcome. In Java, I can forget about it (to a very high degree, anyway), and this enables some algorithms and approaches that would be exceedingly awkward in C++.
There are no objects in Java, there are only references to objects. E.g :
MyClass myClass; // no object is created unlike C++.
But :
MyClass myClass = new MyClass(); // Now it is a valid java object reference.
The best book of Java "gotchas" that I've read is Java Puzzlers: Traps, Pitfalls, and Corner Cases. It's not specifically aimed at C++ developers, but it is full of examples of things you want to look out for.
Specifying a method parameter as final doesn't mean what you at first think it means
private void doSomething(final MyObject myObj){
...
myObj.setSomething("this will change the obj in the calling method too");
...
}
because java is pass by value it is doing what you're asking, just not immediately obvious unless you understand how java passes the value of the reference rather than the object.
Another notable one is the keyword final and const. Java defines the const as a reserved keyword but doesn't specify much of its usage. Also
object1=object2
doesn't copy the objects it changes the reference
All methods are virtual.
Parameterized types (generics) don't actually create code parameter-specific code (ie, List<String> uses the same bytecode as List<Object>; the compiler is the only thing that complains if you try to put an Integer in the former).
Varargs is easy.
I have a method which takes String argument. In some cases I want to pass int value to that method. For invoking that method I want to convert int into String. For that I am doing the following:
aMethod(""+100);
One more option is:
aMethod(String.valueOf(100));
Both are correct. I don't know which is appropriate? Which gives better performance?
Mostly this is happen in GWT. In GWT for setting size of panels and widgets I want to do this.
Using + on strings creates multiple string instances, so using valueOf is probably a bit more performant.
Since you're mostly using it in GWT, I'd go with the ""+ method, since it's the neatest looking, and it's going to end up converted to javascript anyway, where there is no such thing as a StringBuilder.
Please don't hurt me Skeet Fanboys ;)
Normally you'd use Integer.toString(int) or String.valueOf(int). They both return the same thing, and probably have identical implementations. Integer.toString(int) is a little easier to read at a glance though, IMO.
I'd assume that this:
aMethod(""+100);
turns into this by the compiler:
aMethod(new StringBuilder("").append(String.valueOf(100)).toString());
So the option of calling the String.valueOf directly is probably the better choice. You could always compile them and compare the bytecode to see for sure.