I'm trying to write a very simple piece of code and can't figure out an elegant solution to do it:
int count = 0;
jdbcTemplate.query(readQuery, new RowCallbackHandler() {
#Override
public void processRow(ResultSet rs) throws SQLException {
realProcessRow(rs);
count++;
}
});
This obviously doesn't compile. The 2 solutions that I'm aware of both stink:
I don't want to make count a class field because it's really a local variable that I just need for logging purposes.
I don't want to make count an array because it is plain ugly.
This is just silly, there got to be a reasonable way to do it?
A third possibility is to use a final-mutable-int-object, for example:
final AtomicInteger count = new AtomicInteger(0);
....
count.incrementAndGet();
Apache Commons also have a MutableInteger I believe, but I have not used it.
You seem to already be aware of the solutions (they are different though); and you are probably aware of the reasons (it cannot capture local variables by reference because the variable might not exist by the time the closure is run, so it must capture by value (have multiple copies); it is bad to have the same variable refer to different copies in different scopes that each can be changed independently, so they cannot be changed).
If your closure does not need to share state back to the enclosing scope, then a field in the class is the right thing to do. I don't understand what your objection is. If the closure needs to be able to be called multiple times and it needs to increment each time, then it needs to maintain state in the object. A field (instance variable) properly expresses the storing of state in an object. The field can be initialized with the captured value from the outside scope.
If your closure needs to share state back to the enclosing scope (which is not a very common situation), then using a mutable structure (like an array) is the right thing to do, because it avoids the problem of the lifetime of the local variable.
I typically make count a class field but add a comment that it is only a field because it is used by an inner closure, Runnable etc...
Related
I have a method that will process a Collection<Nodes> that is passed in as a parameter. This Collection will be modified, therefore I thought it would be good to first make a copy of it. How do I name the parameter and local variable, e.g. nodes in the example below?
List<Nodes> process(Collection<Nodes> nodes) {
List<Nodes> nodes2 = new ArrayList<>(nodes);
...
}
As another example consider the following where the variable is an int parsed from a String parameter:
public void processUser(final String userId) {
final int userId2 = Integer.parseInt(userId);
...
A good approach to the name variables problem is to use names that suggest the actual meaning of the variable. In your example, you are using names that do not say anything about the method functionality or variables meaning, that's why it is hard to pick a name.
There are many cases like yours in the JDK, e.g. Arrays#copyOf:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
#SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
In this case they call the parameter original and the local variable copy which perfectly expresses that the returned value is a copy of the parameter. Precisely, copying is what this method does and it is named accordingly.
Using the same reasoning for your case (consider refactoring to give more meaningful names to your method and variables) I would name your local copy of nodes something like processedNodes, to express what that variable is and to be consistent with your method's name.
Edit:
The name of the new method you added in your edit does not provide hints about what it does either. I'll assume that it modifies some properties (maybe in a database) of the user whose id is passed via parameter.
If that is the case (or similar), I think that an appropriate approach you
could apply would be that every method should have a single responsibility. According to your method's name it should process the user, for that you need an int userId. The responsibility of parsing an String userId should be out of the scope of this method.
Using the proposed approach has, among others, the following advantages:
Your class won't change if you have to add additional validation to your input.
Your class won't be responsible for handling NumberFormatException which must be the application responsibility.
Your processUser method won't change if you have to handle different types of inputs (e.g. float userId).
It ultimately comes down to what you want to communicate to future programmers. The computer obviously doesn't care; it's other people you're talking to. So the biggest factor is going to be what those people need to know:
What is the logical (abstract, conceptual) meaning of this variable?
What aspects of how this variable is used could be confusing to programmers?
What are the most important things about this variable?
Looking at your first example, it's kind of hard to understand enough about your program to really choose a good name. The method is called process; but methods generally speaking implement computational processes, so this name really doesn't tell me anything at all. What are you processing? What is the process? Who are you processing it for, and why? Knowing what the method does, and the class it's in, will help to inform your variable name.
Let's add some assumptions. Let's say you're building an application that locates Wi-fi access points in a building. The Node in question is a wireless node, with subclasses Repeater, AccessPoint, and Client. Let's also say it's an online-processed dataset, so the collection of nodes given may change at any time in response to a background thread receiving updates in what nodes are currently visible. Your reason for copying the collection at the head of the method is to isolate yourself from those changes for the duration of local processing. Finally, let's assume that your method is sorting the nodes by ping time (explaining why the method takes a generic Collection but returns the more specific List type).
Now that we better understand your system, let's use that understanding to choose some names that communicate the logical intention of your system to future developers:
class NetworkScanner {
List<Node> sortByPingTime(Collection<Node> networkNodes) {
final ArrayList<Node> unsortedSnapshot;
synchronized(networkNodes) {
unsortedSnapshot = new ArrayList<>(networkNodes);
}
return Utils.sort(unsortedSnapshot, (x,y) -> x.ping < y.ping);
}
}
So the method is sortByPingTime to define what it does; the argument is networkNodes to describe what kind of node we're looking at. And the variable is called unsortedSnapshot to express two things about it that aren't visible just by reading the code:
It's a snapshot of something (implying that the original is somehow volatile); and
It has no order that matters to us (suggesting that it might have, by the time we're done with it).
We could put nodes in there, but that's immediately visible from the input argument. We could also call this snapshotToSort but that's visible in the fact that we hand it off to a sort routine immediately below.
This example remains kind of contrived. The method is really too short for the variable name to matter much. In real life I'd probably just call it out, because picking a good name would take longer than anyone will ever waste figuring out how this method works.
Other related notes:
Naming is inherently a bit subjective. My name will never work for everyone, especially when multiple human languages are taken into account.
I find that the best name is often no name at all. If I can get away with making something anonymous, I will--this minimizes the risk of the variable being reused, and reduces symbols in IDE 'find' boxes. Generally this also pushes me to write tighter, more functional code, which I view as a good thing.
Some people like to include the variable's type in its name; I've always found that a bit odd because the type is generally immediately obvious, and the compiler will usually catch me if I get it wrong anyway.
"Keep it Simple" is in full force here, as everywhere. Most of the time your variable name will not help someone avoid future work. My rule of thumb is, name it something dumb, and if I ever end up scratching my head about what something means, choose that occasion to name it something good.
I used to give names, which reflect and emphasize the major things. So a potential reader (including myself after a couple of months) can get immediately, what is done inside the method just by its signature.
The API in discussion receives an input , does some processing and returns the output. These are the three main things here.
If it is not important, what processing is done and what is the type of input, the most generic is this form:
List<Nodes> process(Collection<Nodes> input) {
List<Nodes> output = new ArrayList<>(input);
...
}
and
public void process(final String input) {
final int output = Integer.parseInt(input);
...
If it is important to provide more information about processing and type of an input, names like: processCollection, inputCollection and processUser, inputUserId are more appropriate, but the local variable is still the output - it is clear and self-explained name:
List<Nodes> processCollection(Collection<Nodes> inputCollection) {
List<Nodes> output = new ArrayList<>(inputCollection);
...
}
and
public void processUser(final String inputUserId) {
final int output = Integer.parseInt(inputUserId);
...
It depends on the use case and sometimes it is even more appropriate to elaborate the processing, which is done: asArray or asFilteredArray etc instead of processCollection.
Someone may prefer the source-destination terminology to the input-output - I do not see the major difference between them. If this serves telling the method story with its title, it is good enough.
It depends on what you are going to do with the local variable.
For example in the first example it seems that is likely that variable nodes2 will actually be the value returned in the end. My advice is then to simply call it result or output.
In the second example... is less clear what you may want to achieve... I guess that userIdAsInt should be fine for the local. However if an int is always expected here and you still want to keep the parameter as a String (Perhaps you want to push that validation out of the method) I think it is more appropriate to make the local variable userId and the parameter userIdAsString or userIdString which hints that String, although accepted here, is not the canonic representation of an userId which is an int.
For sure it depends on the actual context. I would not use approaches from other programming languages such as _ which is good for instance for naming bash scripts, IMO my is also not a good choice - it looks like a piece of code copied from tutorial (at least in Java).
The most simple solution is to name method parameter nodesParam or nodesBackup and then you can simply go with nodes as a copy or to be more specific you can call it nodesCopy.
Anyway, your method process has some tasks to do and maybe it is not the best place for making copies of the nodes list. You can make a copy in the place where you invoke the method, then you can simply use nodes as a name of your object:
List<Nodes> process(Collection<Nodes> nodes) {
// do amazing things here
// ...
}
// ...
process(new ArrayList<>(nodes))
// ...
Just my guess, you have got a collection and you want to keep the original version and modify the copy, maybe a real solution for you is to use java.util.stream.Stream.
Simply put, when naming the variable, I consider a few things.
How is the copy created? (Is it converted from one type to another?...)
What am I going to do with the variable?
Is the name short, but/and meaningful?
Considering the same examples you have provided in the question, I will name variables like this:
List<Nodes> process(Collection<Nodes> nodes) {
List<Nodes> nodesCopy = new ArrayList<>(nodes);
...
}
This is probably just a copy of the collection, hence the name nodesCopy. Meaningful and short. If you use nodesList, that can mean it is not just a Collection; but also a List (more specific).
public void processUser(final String userId) {
final int userIdInt = Integer.parseInt(userId);
...
The String userId is parsed and the result is an integer (int)! It is not just a copy. To emphasize this, I would name this as userIdInt.
It is better not to use an underscore _, because it often indicates instance variables. And the my prefix: not much of a meaning there, and it is nooby (local will do better).
When it comes to method parameter naming conventions, if the thing a method parameter represents will not be represented by any other variable, use a method parameter name that makes it very clear what that method parameter is in the context of the method body. For example, primaryTelephoneNumber may be an acceptable method parameter name in a JavaBean setter method.
If there are multiple representations of a thing in a method context (including method parameters and local variables), use names that make it clear to humans what that thing is and how it should be used. For example, providedPrimaryTelephoneNumber, requestedPrimaryTelephoneNumber, dirtyPrimaryTelephoneNumber might be used for the method parameter name and parsedPrimaryTelephoneNumber, cleanPrimaryTelephoneNumber, massagedPrimaryTelephoneNumber might be used for the local variable name in a method that persists a user-provided primary telephone number.
The main objective is to use names that make it clear to humans reading the source code today and tomorrow as to what things are. Avoid names like var1, var2, a, b, etc.; these names add extra effort and complexity in reading and understanding the source code.
Don't get too caught up in using long method parameter names or local variable names; the source code is for human readability and when the class is compiled method parameter names and local variable names are irrelevant to the machine.
I am parsing a text file looking for syntax matches. to complete this task, I created Variable class with static variables in it. Then I parse a file and I assign the parsed information to the variable class static elements.
Variable.name = "the parsed information";
Then I created a Baseline class to check and compare against the Variable elements to check if certain condition is met.
For example
if (BaseLine.x.equal(Variable.x) // do whatever.
Variable Class:
public class Variable {
static String name;
static String userID;
static Integer age
}
BaseLine Class:
public class BaseLine {
static String name;
static String userID;
static Integer age
}
Utilizing JavaFX I move between scenes to load a file, parse it, assign the parsed variable then compare it with my BaseLine class. Thus far, Everything works as expected until I hit the back button to go back to the original scene to load a new file. now, the issue that I am having how can I reset the variable inside my Variable class in bulk instead of doing it one by one inside my controller initialize statement? I want to do this to ensure that I don't capture any variable from the older file I just parsed before I hit the back button. what is the correct way of completing this task?
I was able to get what I am looking for when I reset the variables inside my initialize controller, but it seems to be a lengthy process to do for OOP I have over 100 variables (int/sets/strings...) to reset.
Here is what I did to reset the static Variables inside the controller initialize section.
#Override
public void initialize(URL url, ResourceBundle rb) {
Variable.name = null;
Variable.setName.clear();
Variable.age = null;
I was able to get what I am looking for when I reset the variables inside my initialize controller, but it seems to be a lengthy process to do for OOP I have over 100 variables (int/sets/strings...) to reset.
If you have hundreds of static variables, you are not doing OOP properly. In proper OO design, your application's state should be held in instance variables, and accessed via instance variables. Static variables should be kept to an absolute minimum. (You can eliminate them entirely, if you can use a dependency injection (DI) framework ...)
The bad news is that there is no >>good<< way to reset a large number of
static variables. There are a couple of >>bad<< ways; e.g. reflection, and messing around with classloaders ... but you just would be replacing one problem (clunky code) with a worse one (complex, fragile code). IMO.
But the good news is that you fix your design / implementation to be properly OO, then you won't have this nasty problem of resetting the variables. And a whole bunch of other things will be easier too ... like writing unit tests.
I am not aware of a way that would exists that would allow you to reset all static variables in one go. You would have to do one by one.
I think your problem lies somewhere else - and i believe you should refactor your code in that instance (if possible).
How about having all your variables as standard (non static) and set/get them like you normally would but when done just create new object and let the old one be collected by Garbage collector??
Edit:
Although you could perhaps use reflection ? Not entirely sure if that would work though.
Something like
Field[] fields = MyClass.class.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers() && isRightName(field.getName()) {
field = null;
}
}
I have a method that list the elements of an ArrayList, typically it prints the components of a global variable ArrayList, but in one specific instance I need it to print the components of a local variable.
So I have this
public static void listPlayers(ArrayList<Player> characters, boolean beingRolled) {
//print character components (beingRolled specifies which parts of each players to print
}
and I use that when I'm using the local variable ArrayList,
when I want to use the global i call this version
public static void listPlayers(boolean beingRolled) {
listPlayers(players, abitraryBoolean);
}
where players is the global variable
Another thing I was thinking about is anywhere I want to use the global I could pass a null reference for characters and write this method
public static void listPlayers(ArrayList<Player> characters, boolean beingRolled) {
if (characters == null) characters = players;
//print components
}
Which is the more professional/recommended version?
In general, stay away from null; the overloaded method signature is a better approach.
That said, one thing you said is scary -- You have a static method operating on a global variable. In general, that is a bad idea. You should consider refactoring to use Object/class scoped state, rather than global, static scoped state.
I would even go so far as to say that you should only use the overload that takes the ArrayList as a parameter, and pass it the global variable every time. Then, even if you must use a global variable, at least you're using it in one fewer place.
Edit: One of my professors back in college wrote a book on refactoring that is very readable and has a lot of good content (though the typography is a bit odd). It's called Principle-Based Refactoring: Learning Software Design Principles by Applying Refactoring Rules, by Steve Halladay. I highly suggest reading the first half (second half is essentially a reference).
The first version is better because it is easier for someone else to understand. When a function's arguments are all listed, the caller can more easily predict what the function will do. If the function relies on variables which are not visible, say if this is available in a library without the source, the caller will not understand why the function acts in an unexpected way. This would be impossible to understand without good documentation.
I am starting to develop for Android (And I am starting to think, does it worth it!). Eclipse keeps giving me a lot of strange warnings and errors too! Here is one that kept me frustrated for the last two hours with no luck on Google:
private String alertTitle= null;
There is an ! mark beside it saying Remove "alertTitle", keep assignments with side effects. What is this?! I am defining a variable exactly as Java states. I am using the variable later:
public ASAlertDialog setTitle(String title) {
this.alertTitle = title;
return this;
}
Another one that's a little bit similar is defining enum"
public enum MyStyles {
aStyle;
}
public MyStyles myStyle = aStyle;
This made Eclipse angry!
You may be using the variable name by assigning a value to it, but you are not using the value stored in the variable. To do that, you must use the variable name to retrieve the stored value, and do something with this retrieved value somewhere in your code.
Eclipse tags the variable as unused when the value is never retrieved (or more generally, it's never possible to retrieve it*). It means you're merely assigning values to it, but never making use of them anywhere. This makes the variable an unnecessary memory hog, hence the warning.
* public and protected variables won't get the warning because they can be retrieved in other classes even if they aren't retrieved within the class they are declared in, and even if they are currently never retrieved in any class (it may happen in the future due to library use).
For the enum, it should be:
public MyStyles myStyle = MyStyles.aStyle;
This is because an enum is something like a class, with the constants acting similar to static variables in the class. (This is just an analogy, not exact an language definition.) You would retrieve enum constants the same way you retrieve variables from an external class that are defined as static.
Your variable is not used, so eclipse informs you about that and therefore you get message Remove "alertTitle", keep assignments with side effects
For enums, you need to declare it as
public enum MODE
{
NO_ASYNC_TASK,
NO_DOWNLOADED_DRAWABLE,
CORRECT
};
Check my this answer for more information
And the warning is because you might not be using alertTitle variable after declaring it.
To your first question:
It just means that your variable isn't being used, so you can safely remove it. The warning will disappear once you start using the variable in your code. Side-effects are explained here:
http://www.cs.umd.edu/~clin/MoreJava/Intro/assign.html
Check under "Is Assignment an Expression?"
To your second question:
There is no ';' in defining an enum. Check this:
http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
Try
public enum MyStyles {
aStyle;
}
public MyStyles myStyle = aStyle;
Regarding to your String, maybe Eclipse informs you that your variable is never used.
By the way,
private String alertTitle;
is null by default, so why do you set "= null"?
The discussion around global variables and their misuse seems to hold a certain dogmatic tone to it. I am not here to dispute the "globals are bad" concept as it makes sense to me why they are bad. However I was wondering if people had some interesting code snippets that demonstrate exactly how to effectively refactor higher scoped variables and objects out of the code. In this question I am looking for examples or patterns of generic but useful solutions to the "I need to use a global variable here because it is easy" problem.
Here is a hypothetical and perhaps contrived example. I am using the global variable to keep track of the parameters sent to a function. And then if there is a failure that happens further down the chain I could go back and call the function again using parameters from the global variable.
public var myGlobalState:Object = new Object();
public function addPerson (name:String, person:Object, personCount:int, retryCount:int):void
{
myGlobalState = null; // Clear out old values
myGlobalState = new Object();
myGlobalState.name = name;
myGlobalState.person = person;
myGlobalState.personCount = personCount;
myGlobalState.retryCount = retryCount;
person.userId = personCount + 1;
person.name = name;
savePerson(person);
}
public function savePerson (person:Object):void
{
// Some code that attempts to save the person object properties to a database...
// The process returns a status code for SUCCESS of FAILURE.
// CODE TO SAVE TO DATABASE ....
// Return status code...
if (status == "fail")
{
// Retry at least once by calling the addPerson function again
if (myGlobalState.retryCount < 3)
{
addPerson (myGlobalState.name, person, myGlobalState.personCount, myGlobalState.retryCount);
}
}
}
I don't have a snippet, but I have a real world example.
Linear calibration constants (mass spectrometry field) in an
application were global and there was complicated code to
store and restore the global calibration constants for
different spectra. Usage of the two values was spread all
over the program, and it was difficult to change or check
that conversion between uncalibrated and calibrated mass
values using the two constants was correct in all cases.
I refactored by encapsulating the two calibration constants
in a class that had the responsibility of converting between
uncalibrated and calibrated mass values. Functions to do the
conversion were also introduced so it was centralised in one
place in the program instead of being spread all over the
program. This encapsulation later made it easy to introduce
a new kind of calibration (not linear).
Instead of accessing the two global variables the class
that represented a spectrum would instead have and use an
instance of the new calibration class, each instance with
its own set of calibration constants.
A quick solution would be by adding all your global variables inside one huge object, possibly with several child objects to separate the groups of data. With all those variables in one object, all you would need is one global variable to store this object. All your code would then refer the variables in this object instead the global variables.
The next step would be getting rid of this single, global object. And that should be easier than getting rid of a few hundreds of global variables. This could be done by changing it into an additional parameter that you pass along to any other methods.
Once all global data is gone, you can think about refactoring your code, trying to optimize this shared object by e.g. dividing it into multiple smaller objects. But by moving everything inside a single object, you make it all easier to manage.
The answer usually lies in the architecture of your program. You could design in in a way global variables are absolutely necessary and you could design in in the way you never need them. You would usually end up with a better and cleaner architecture in the later scenario plus would avoid all of the usual problems with creating unit tests for the methods which rely on the global variables etc.
This question will also help.
P.S. In your particular scenario the global variable is not really needed at all - you could easily pass it as a parameter to the addPerson method.