Related
I'm no really sure how to explain my doubt right away, so I'll start with an example. I have the next lines:
Object myObject = null;
Integer myInteger = 10;
myObject = myInteger;
Basically, I know I can assign one subclass object to a superclass object (in this scenario, myInteger of type Integer to myObject of type Object). So far so good, but now... let's say I want to get the class of myObject.
System.out.println("myObject: " + myObject.getClass());
And it prints this:
myObject: class java.lang.Integer
It says is of type Integer!
I know a variable actually stores a reference to the actual object in memory, so the method getClass() is returning the class of the actual object. But then...
Why can't I access the methods of the class Integer through myObject since is pointing to an object of type Integer? I mean, why can't I do something like this? myObject.intValue();
If I can only access to the methods of Object through myObject (even though it's pointing to an object of type Integer), how does Java know which methods can be called through myObject? the variable itself stores a type of class?
Basically, I would like to know what information Java stores in the variables, is it only a reference? or it also has a class name? how the variable know which methods can be called if it has assigned a reference to a subclass object?
I hope my doubt is clear, and excuse my grammar.
The answers to your questions essentially boils down to two key points: "the compiler doesn't let you do dangerous stuff" and "the compiler isn't as smart as you think".
Why can't I access the methods of the class Integer through myObject since is pointing to an object of type Integer?
You know that because you see that the line myObject = myInteger;, so you know that myObject is going to have an intValue() method.
When the compiler sees you call myObject.intValue();, it doesn't go back a few lines (like you do) to find out what is actually referenced by myObject. It just sees that its type is Object, and allows you to use only the stuff available defined in Object. Since it doesn't look back at what myObject actually refer to, as far as the compiler is concerned, myObject could refer to an Integer, but it could also refer to a String, because you could have done:
myObject = "Hello";
String doesn't have an intValue() method. "Better safe than sorry", says the compiler, and doesn't let you call intValue. You can tell the compiler that you know better by casting:
((Integer)myObject).intValue();
how does Java know which methods can be called through myObject?
That is determined by the type of the expression. The expression myObject is of type Object, because the variable myObject is of type Object. On the other hand, the expression ((Integer)myObject) is of type Integer.
Consider this analogy: you provide storage services with three tiers of "safety level": General goods, Valued items, and Luxury items. You have an online system that lets your clients book space and make payments based on what they want to store. Depending on the tier, your services and booking requirements are different:
General goods:
You get space in shared warehouse
You pay by item volume
Valued items:
You get storage space in shared warehouse
You get additional security with camera surveillance
You pay by item volume
Luxury items:
You get dedicated storage space with a location label
You get camera surveillance and security guards watching your items 24/7.
You pay by item value.
Now, consider that your clients bring items in boxes marked with a reference number issued by your reservation system and your security guards on location inspect the content.
Let's see what your process steps do:
Online system:
Lets your clients declare what tier they're going to buy
Reserves storage room for the declared booking
Based on client's booking, charges their payment method with the correct amount
Offers a tracking system that shows basic details of physical storage
Security guards:
Inspect the actual physical items clients present in a box
Ensure items are as per booking, but gold can be stored in general goods area if the client chooses to do so, but old plastic cups can't be taken to luxury items for insurance's sake.
What do you think of these scenarios?
A client uses your online system to book general goods storage and completes the booking. When they come back to check the status of their items: will the system let them see the name of the security guard watching their item 24/7?
Hint: no, the system knows that they have general goods tier and that offers no dedicated guarding services.
The same client puts gold in the box and presents it at the location.
Will the online system let them see details of 24/7 guarding or the video footage?
Hint: no (still), because the system knows that it's a general goods reservation.
Will the guard who checked them in know that it's gold in the box rather than cheap items?
Hint: yes. But still, the client will not get luxury items service. Right?
A different client makes a "luxury items" booking, but presents a box with an old plastic cup inside.
Will your online system prevent them from doing this?
Hint: no, it can't, because it doesn't know what's in the client's mind and it can't inspect the item.
Will your guard on-site be able to prevent this box from being checked in?
Hint: yes, because they can see the physical item and determine what it actually is. And because insurance forbids low-value items in higher tiers, the guard can stop this.
So it is with Java (roughly speaking):
Declaring a variable and giving it a type => making a booking and declaring the kind of good
Assigning a value to a declared variable => putting an item in a box and presenting it to the guard for inspection
Calling a method on a declared variable => using services or tracking online (you can't get services your tier doesn't entitle you to: even if you have gold in general goods, you can't get video footage)
In other words, the online system is like the compiler, and the physical location is like the runtime.
In Java, the type of tier you reserved online is known as "static type", it's the type known at compile-time (at booking time). The actual type you put in the box is known as the "runtime class", being dynamic (just as a general goods tier box can be allowed to take in gold, or a mid, valued item like a TV).
Just as with the box, only the runtime knows the actual/runtime class of the variable: only the staff on-site will know that it's gold in the box. And when you call myObject.getClass(), that's exactly what you're asking for: the runtime class of myObject (this is the class whose constructor is called or with which new is used; or in some cases, the class of the literal, such as 10 for int or Integer, but this is a story for another day). But even if at runtime it's known to be an Integer, the compiler (online system, remember?) won't let you call methods that are on Integer because myObject was declared as Object: the online system won't let you see video footage of a general goods booking even if the box holds diamond. You can force the compiler to accept Integer's methods on myObject with a type cast, as shown in Sweeper's good answer, and this is a little like upgrading to luxury items on site, after which the online system will let you get higher tier services :)
This analogy is possibly ridiculous in some aspects, such as in the fact that the compiler prevents you from assigning an incompatible or broader-typed value to a variable... but it's just an example, a limited one.
I want to run a method which sends notification e mail to users in java. But how can I tell the program "run the method if variable's value haven't changed for last 24 hours" ?
Simple: by writing code for that. What you will need:
some sort of "time aware" data store. In other words: a plain field within your class won't do. Like, when you have class Person { String lastName ... ... tracking changes directly on a field of a Person object isn't possible. In other words: you need to write your own code that gets told "update the value for key X" ... and whenever that happens, you store the time stamp of the change. The most simple approach: have setter() methods that store that timestamp. But that idea doesn't scale, and would lead to a terrible design.
a service that regularly comes in and checks these timestamps, to then make decisions about that.
And hint: given the fact that your question is very broad and unspecific, don't expect more specific answers (or even code) coming back.
Short answer: you can't. What you can do is save a copy of the variable's value, and schedule a task to be executed periodically, compare the variable's value with the one you saved, call the method if it's different, and save the new value.
UPDATE
After a exchange of comments, I will point out that I would not recommend that solution in the case where you can control the assignments to variable (for instance if there is a setter for that variable, and you can alter the code of that setter), in this case, I would rather recommend a solution like the one posted by GhostCat.
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.
As part of my AP curriculum I am learning java and while working on a project I wondered which of the following is best way to return a value?
public double getQuarters(){
return quarters;
}
or
public void getQuarters(){
System.out.println(quarters);
}
***Note: I now that the second option is not "technically" returning a value but its still showing my the value so why bother?
Your answer would be correct. The second method doesn't return any value at all, so while you might be able to see the output, your program can't. The second method could still be useful for testing or even for a command line application, but it should be named something like printQuarters instead.
public double getQuarters(){
return quarters;
}
Use this incorder to encapsulate quarters and hide it from being accessed by other programs. That means, you have to declare it as private quarters. Let see the second option:
public void getQuarters(){
System.out.println(quarters);
}
However, this seems wrong as getQuarters is not returning anything. Hence it would make more sense to refactor it as
public void printQuarters(){
System.out.println(quarters);
}
You answered your own question. For most definitions of the word "best", you should go with the first option.
Your question, however, does touch on the object-oriented programming topic of accessors and mutators. In your example, "getQuarters" is an accessor. It is usually best to use accessors to retrieve your values. This is one way to adhere to the Open/Closed Principle.
Also, the Java community has a coding convention for this and many tools and libraries depend on code following those conventions.
If all you need to do is display the value when this method is called, and you are ok with console output, then your System.out.println method will do the job. HOWEVER, a function that actually returns the variable is much more semantically correct and useful.
For example, while you may only need to print the variable for your current project, what if you came back later and decided that you were instead going to output your variable to a file? If you wrote your getQuarters function with a println statement, you would need to rewrite the whole thing. On the other hand, if you wrote the function as a return, you wouldn't need to change anything. All you'd have to do is add new code for the file output, and consume the function where needed.
A returning function is therefore much more versatile, although more so in larger code projects.
You return values to a specific point in your program, so that the program can use it to function.
You print values at a specific point in your program, so that you as an end user can see what value you got back for some function.
Depending on the function - for instance, yours - the result of quarters is no longer regarded in the program; all it did was print a value to the screen, and the application doesn't have a [clean|easy] way to get that back to use it.
If your program needs the value to function, then it must be a return. If you need to debug, then you can use System.out.println() where necessary.
However, more times than not, you will be using the return statement.
Option 1 is far superior.
It can be easily Unit Tested.
What if the spec changes and sometimes you want to print the result, other times put it into a database? Option 1 splits apart the logic of obtaining the value from what to do with it. Now, for a single method getQuarters no big deal, but eventually you may have getDimes, getEuros, etc...
What if there may be an error condition on quarters, like the value is illegal? In option 1, you could return a "special" value, like -1.0, or throw an Exception. The client then decides what to do.
I m trying to develop a simulation application. I need to monitor all java objects in simulation environment. During the execution of a simulation, user defined objects methods are called periodically in each tick. I want to trace all field values and method return values of all objects. For example,
public class Person{
int energy,x,y;
public Person(){
this.energy = new Random().nextInt(0,10);
}
#ScheduledMethod(start=1, interval=1)
void step(){
energy--;
// move random x,y
move();
}
void move(){
this.x= new Random().nextInt(1,50);
this.y = new Random().nexInt(1,50);
} }
In my simulator each person instance energy value in each tick until person is dead is traced and saved. Simulation developers generally uses randomized functions so calling a method twice may not be return the same value like x,y value of the Person.
By using reflection API i can access field values dynamically (energy value of the person can be accessed.) but i need to access method return values (x,y value of the person is changed in each call of the move). When i call method using reflection execution of the method is twiced. So, i need to handle method calling differently.
I mention that i need a monitoring mechanism like JAVA Debugging API. How i can do that during the execution of simulation.I need to watch all fields and method return values like debugging code in execution.
Any idea.
Thanks for ideas
If I understand what you're asking correctly, you want to capture changes in values of raw fields after a call to a method with your annotation.
There are a lot of possible solutions to this, depending on how simple the client code needs to be, and how complicated a framework you want to write, and what you actually need it to do. Here are some ideas:
Have a common base class for simulation objects, and give subclasses a way to store values in a Map<String,Object> you give them, instead of in a raw field; they you supply a subclass of Map which records changes, and your code can simply ask the object what has changed since the last time it was called
Instrument the bytecode on the fly when you load it, using something like BCEL, and replace local field accesses with calls to dynamically generated getters and setters, and do the above bookkeeping there
Do the above, but at compile time by dynamically generating subclasses which contain the bookkeeping code
The last two options are non-trivial to implement, so I'd strongly suggest considering the first option first.