Referencing not-yet-defined variables - Java [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Because I'm tired of solving math problems, I decided to try something more engaging with my very rusty (and even without the rust, very basic) Java skills. I landed on a super-simple people simulator, and thus far have been having a grand time working through the various steps of getting it to function. Currently, it generates an array of people-class objects and runs a for loop to cycle through a set of actions that alter the relationships between them, which I have stored in a 2d integer array. When it ends, I go look at how much they all hate each other. Fun stuff.
Trouble has arisen, however, because I would like the program to clearly print what action is happening when it happens. I thought the best way to do this would be to add a string, description, to my "action" class (which stores variables for the actor, reactor, and the amount the relationship changes). This works to a degree, in that I can print a generic message ("A fight has occurred!") with no problem. However, ideally I would like it to be a little more specific ("Person A has thrown a rock at Person B's head!"). This latter goal is proving more difficult: attempting to construct an action with a description string that references actor and reactor gets me a big old error, "Cannot reference field before it is defined." Which makes perfect sense.
I believe I'm not quite in programmer mode, because the only other way I can think to do this is an unwieldy switch statement that negates the need for each action to have its own nicely-packaged description. And there must be a neater way. I am not looking for examples of code, only a push in the direction of the right concept to handle this.

Wow. Quite a large wall of text. Hence:
Breakdown
Your setup
Currently, it generates an array of people-class objects and runs a for loop to cycle through a set of actions that alter the relationships between them, which I have stored in a 2d integer array.
I would like the program to clearly print what action is happening when it happens.
I thought the best way to do this would be to add a string description to my "action" class (which stores variables for the actor, reactor, and the amount the relationship changes).
It sounds like your Action class so far looks something like this:
public class Action {
private String reactor;
private String actor;
private double hateMeasure;
/* Obligatory constructor method, getters, and setters go here */
}
Your trouble
I would like it to be a little more specific ("Person A has thrown a rock at Person B's head!").
... attempting to construct an action with a description string that references actor and reactor gets me ... "Cannot reference field before it is defined."
At this point I'm not quite sure how you're setting up your reference fields, and exactly how you're running into this error.
I know you weren't looking for code, but you must appreciate the difficulty of getting somebody into "programmer mode" without showing them some skeletal principle-illustrating code.
Perhaps create a method that takes two parameters of the actor and reactor, and then call that method after each action happens?
public void reportAction(String reactor, String actor) {
// do stuff
}
/* if you're confused by how "reactor" and "actor" have the same names as
the instance variables, look into the "this" keyword */
Alternatively (if your setup was different from what I inferred from your description, add in those instance variables and then) you can simply write a new method in your Action class that takes no parameters and simply references your instance variables:
public void reportAction() {
System.out.println(actor + " with " + reactor);
}
Now it occurs to me that you may wish to specify what happened between the reactor and actor instead of simply stating that something happened between two specific simulated people. In that case...
public void reportAction() {
System.out.print(actor);
// you're going to have to define the change in hateMeasure here
if( deltaHateMeasure > 0 ) {
System.out.print(" had a fight with " + reactor);
} else { /* print other stuff */ }
}
Another fun thing for you to look at would be ternary operators, if you'd like to code this succinctly.
Have fun!
EDIT:
Even better!
Add in a String descriptor; instance variable to your class!
Then it all comes down to...:
public void reportAction() {
System.out.println(actor + descriptor + reactor);
}

I am not exactly sure how you wrote your classes. Am I correct in assuming that at the time that you want to print your string, you do know the names of the actor and reactor?
If so, you should be able to do something along these lines:
System.out.printf(action.description, actor.name, reactor.name);
In which case action.description (or wherever you store your description string) looks something like:
"%s has thrown a rock at %s's head!";
I hope this helps!

Related

Better to reference field instance or parameter in this constructor? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I've written this 'CoreException' Exception subclass. I appear to have three options in the constructor that would all behave identically since they are all referencing the same object.
*note: the question is about the compiler and possible runtime difference from the three different source code options. The constructed Object could be of any class.
public class CoreException extends Exception {
private final Class<?> sourceClass;
private final Method sourceMethod;
public CoreException(#NotNull Method method, #NotNull Throwable thr) {
super("this text is irrelevant", thr);
this.setStackTrace(thr.getStackTrace());
this.sourceMethod = method;
this.sourceClass = this.sourceMethod.getDeclaringClass();
}
public Class<?> getSourceClass() { return sourceClass; }
public Method getSourceMethod() { return sourceMethod; }
}
The construction of the Class<?> sourceClass object seems to have three identical options:
this.sourceClass = this.sourceMethod.getDeclaringClass();
this.sourceClass = sourceMethod.getDeclaringClass();
this.sourceClass = method.getDeclaringClass();
Is there a decent reason to use one over the others, perhaps because of a marginal increase in performance, reliability / resilience, etc..?
Or does the compiler simply turn all three of these into exactly the same result?
In the example, there is no difference between this.sourceMethod and sourceMethod, the resulting bytecode will be the same. It is just a matter of taste which you prefer. Some people prefer using this. always, while others prefer to only use this. when it is necessary for disambiguation if there is also a local variable with the same name.
The only real difference is between [this.]sourceMethod and method: sourceMethod is a field on the object, while method is a parameter. Given method is a parameter, it's on the stack, and it's probably slightly faster than accessing the field sourceMethod of the object. However, in the grand scheme of things, this difference is likely negligible, and even if it's not, it is entirely possible that the JIT compiler optimizes it in a way they are equivalent. If you really need to know, you should write a micro-benchmark to measure that difference.
Personally, I would consider the choice between using sourceMethod or method primarily one of opinion.
This is a bad idea. You're trying to address a thing you find uncomfortable about java, the language, with an API update. This cannot work - the vast majority of exceptions out there just will not be wrapped in a CoreException (e.g. anything that the java core API itself throws, or anything in any third party library such as JUnit, JDBI, etcetera).
Your code will no longer be making sense to other java programmers who do not expect to need to reroute all exceptions through this class of yours.
You also won't be able to write code that 'fits' in existing APIs (i.e. implementations of interfaces), as you will be required to write your own variants of all relevant exception types (as they will need to extend CoreException somewhere in the hierarchy, and the exceptions in java.* and anything written in e.g. jdbi.* wouldn't, and you can't update them to without forking every library you use).
So what DO I do?
The info you are sticking in that exception message are already available in plain jane exceptions - the first line of the stack trace. It's silly to repeat this information in the message.
If you have some logging or error reporting system where currently you do not have this information, and you want it to, that is a real problem. You've just decided to solve it in an unwieldy and inadvisable way.
Instead, updating whatever that system might be to include the first line of the stacktrace. This is generally not hard, but it depends on where the place is that made you go: "Oof, I could really use the method name here".
Note that going your own way has more downsides than just 'it stands out in existing APIs like a sore thumb'. IDEs will not recognize this and you won't be able to click on the class+methodname in the message to automatically jump to the right file. You need to match the 'style' of what StackTraceElement prints if you want that.
Your code also causes straight up erroneous conclusions. This approach (of having a Method object that represents the source) doesn't make much sense when the exception is thrown from within a lambda.
Thus, abort the plan. Whatever you wanted to accomplish by making Method sourceMethod part of the state of all of your exceptions - you either didn't want that, or you can accomplish it far better in a different way (and probably by relying on getStackTrace()[0]) to convey it.
public Class<?> getSourceClass() {
return Class.forName(getStackTrace()[0].getClassName());
}
can do the job just as well, for example, though note that this code may fail (throw ClassNotFoundEx) depending on where the exception came from. Not all code is easily captured in a 'it is in this class and in this method' context (core stuff, native stuff, synthetic methods, bridgers, dynamically generated code, lambdas...)

Is there an elegant way to check many conditions and call corresponding functions?

So, say I've got lots of values and flags passed into my program from the command line, all stored as variables in some configuration object, config. These variables default to null if they are not provided by the user.
I've then got some other object, say an instance of Dog, which has lots of methods. Depending on the value of a specific command line argument, I may or may not want to call a specific method, possibly passing the argument value to the method.
At the moment I'm doing that like this:
Dog dog = new Dog();
if (config.argumentA != null) {
dog.methodA(config.argumentA);
}
if (config.argumentB != null) {
dog.methodB(config.argumentB);
}
if (config.boolArgument) {
dog.methodC();
}
// ... ... ...
if (config.argumentZ != null) {
dog.methodZ(config.argumentZ);
}
Now I've tried to look for a more elegant way of doing this, since this feels very dirty, but Google and Java jargon have me stumped.
I'm imagining making a map from the arguments' names to the function names, then looping through, checking each argument's value and calling the corresponding method. Does such a mapping exist in Java? Is there any way to do this nicely, or am I going about the problem completely wrong?
P.S.: I'm a bit of a beginner with both Java and problems like this, so pls be gentle :)
Actually this question relates to the programming practices. So like Alan Kay said OOP is basically message passing. Thus your code should not be making these decisions but rather passing this info to some other method of some other class, till the time it's actually needed. Now if you couple this concept with different Design patterns you'll get an elegant piece of code.
Also it's difficult to suggest a particular solution to a problem as abstract as your's.

ActionListener acting wierd

I am having a problem with my ActionListener's not acting as (I think) they should. I have the below code:
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
final String text = textField.getText();
if (text.toLowerCase().replaceAll("'", "").contains("whats new")){
textArea.setText("Oh, you know...work...college. I am a computer science major and software engineer.\nDo you program?");
if (text.toLowerCase().replaceAll("'", "").contains("yes")){
textArea.setText("Cool!");
}else{
textArea.setText(":(");
}
}
}
});
The textField is where the user types the question, and the textArea is where the program answers.
The problem is, when I type "whats new", then "yes", it gives me the default string I set for when it doesn't understand.
You're not thinking fourth-dimensionally! (kidding aside now)
You are attempting to handle the sequence of events at once in your listener but your listener will actually be called multiple times: once for an answer to the first question and a second time for a reply to your follow-up comment.
You need to make your listener handle both of these states independently. You probably need to capture the state of your last asked question in the class scope and check it in your listener to determine what question was asked so you will know how to evaluate the contents of text and give the proper reply.
You will probably not study finite automata or formal study of state machines for several more semesters, but it's a crucial step to have elementary understanding of. Without knowing the problem statement provided, I assume the assignment is trying to push you into that direction. Also, in any paradigm, though for Java we'll stick with OO, there are many ways to add some layers of beauty and fault-tolerance for a better solution, but my intent is to stick with what is simplest for you. For example, you could make a class that represents each state pending the user's response (question 1, question 2, etc.) and model the states and transitions within your application. Each state as modeled would know of the question asked, potential answers, and transitions to other states. In an OO system, each of these states would have an API and operate via some call like execute() which would evaluate the current state of the system and determine a transition. Do some more research on this on your own.
Back to your simpler example. Let's say you only have two cases, one for each question: "what's new" and "do you program". Store some representation in your class (named constants are good practice):
class Interrogator {
String q1 = "what's new";
String a1 = ...do you program?";
String q2 = "yes";
...
}
Now in your actionPerformed, test the contents of both your question-text-area against known questions and your answer area against known responses: if (a1.equals(textArea.getText() && q2.equals(text.getText())) then you know you the answer to the initial (unprompted) question is displayed and an expected response was entered. Don't forget your formatting translation (to lower case, strip quotes).
It gives you the default because the second if statement is inside the first. When the first test is true, the second test which nested inside the first test will be false casing the else clause to override your textArea with default text. You should do something like this
if (text.toLowerCase().replaceAll("'", "").contains("whats new")){
...
}
else if (text.toLowerCase().replaceAll("'", "").contains("yes")) {
...
}
else {
...
}

Java dice random numbers [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I posted about this yesterday, but I think I need to make it less involved. I have absolutely no Java experience, and I need to work on this "Dice" program. I've done it twice already, but clearly I still have no idea what I'm doing. I've also been pouring over examples on here and elsewhere online, but none of them exactly match what I'm doing, as they all say "Pair of Dice".
Mine says: "Create a class called Dice to represent a SINGLE cube". It should have a method called roll() that randomly selects a number from 1-6 for the value of the dice."
It has to use java.util.random, not math.java, and it has to have numberShowing:int, roll():int, and main() all in it.
The last part reads "Create a test main method for the Dice class that creates a dice and rolls it many times. Can you keep track of how many times a number comes up? Describe how or implement it in the program."
I have started at this computer for hours, and read as much info as I can. I can't tell you how high my anxiety level is right now, nor how much I despise this. Please help me get this code written.
First, don't panic. It's hard when things are new and don't be discouraged if you don't know where to start.
Here is the documentation for java.util.Random: http://docs.oracle.com/javase/7/docs/api/java/util/Random.html
Your first job is to work out how to read this and understand it. Try Googling "java understanding api documentation" or similar.
It describes how the class you've been told to use works.
You will also need to know how to define a class of your own, called Dice with an instance variable numberShowing and instance methods roll and main. You can research these things by Googling something like "java introduction tutorial create class" or similar for each of these.
Here's a quick rundown of what you need to know (but know the approaches above for future problems):
Declaring a class named Dice:
File: Dice.java (name must match class name below)
public class Dice {
}
Adding an instance variable numberShowing:
You need to know what type the variable needs to be. You have been told to use an int which represents an integer value (a whole number):
File: Dice.java
public class Dice {
int numberShowing;
}
Adding a method roll():
You need to know what type of value this method returns, and the types of any values it can be given to perform some calculation or action. In this case you have been told it doesn't take any values and returns a value of type int (this is what I assume is mean't by roll():int in your above description - that is, empty parenthesis for no values passed in and :int to indicate the method returns an int):
File: Dice.java
public class Dice {
int numberShowing;
public int roll() {
/* code to perform calculation goes here */
}
}
You need to place the code to perform a random roll and assign the result into numberShowing at the point where I have the comment above (the comment is denoted text enclosed in /* and */).
You will need to create an object of the java.util.Random class. To do this you will need to import this class. Then you need to create using its constructor, and call an appropriate method - be sure to check the API document to understand how the method works.
File: Dice.java
import java.util.Random;
public class Dice {
int numberShowing;
public int roll() {
Random random = new Random(); /* <-- this is a constructor */
numberShowing = random.nextInt(6) + 1; /* <-- look at the API doc for nextInt() to see why we give it 6 as and argument, and why we need to add 1 to the result */
}
}
Adding a static method main():
This is the standard entry point for running a class as a program. You should be able to find an example of this easily by googling any getting started or introduction to java tutorial. (Sorry, I ran out of time).

When should encapsulation be used? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am completing Sun/Oracle's Trail (http://docs.oracle.com/javase/tutorial/java/TOC.html) and it keeps reiterating the importance of encapsulation.
How important, really, is encapsulation? I mean, if I may need to access the value of a given class field, why would I do so through a method when I could just access the field directly? Since the field would be accessed through its corresponding object anyway, where could this really go wrong?
Is it just for code extensibility purposes? In other words, because that way in the future if I decide I want to somehow alter or sanitize the field before returning it I can?
I'm more looking for an example or two than anything.
Validation.
If you don't use a method, you can't add any validation on the field unless you validate it at every place you want to access the field: unsustainable.
It also separates the data from your class from the outside world. By hiding the actual implementation of data behind methods, you can manipulate your data the way you want (now and in the future) and no other pieces of code will get broken. This allows you to change the way something is represented without a problem, as long as you make sure it can still be returned trough the existing method.
Encapsulation is not only a matter of making getter and setter for a field.
It's about:
Validation (and also consistency)
Hidding implementation (programming to an interface not an implementation)
Getters and setters don't have to reflect the acutal fields. There could be getters (and even setters) for fields which value is calculated on demand
Hide complexity: A getter/setter could peform something more complex than just setting a value
Advanced: Use of a diffrent implementation/modification; patterns like lazy loading which is used in ORM framework wouldn't work if you would use public fields
Even if you as you said "need to access the value of a given class field" you can't be sure that this requirement won't change (cause it will most time).
Actually, I think you're thinking about this the wrong way. The issue isn't encapsulation per se, it's decoupling the behavior of your objects from their data.
Fields are data -- they are part of the internal state of the object. Methods are part of the object's API. Objects shouldn't just be clusters of fields -- if your objects are just dumb collections of data, then that's not object-oriented programming, that's just structured programming.
Objects should be designed to represent real-world entities, and have methods that represent operations you could take on those real-world entities. To put it another way, you don't ask an object for its fields (e.g. getFoo(), getBar()) to pass those to other functions -- instead you should put the relevant operations (e.g. purchase(), validate(), etc.) as methods directly on the object.
That said, there's nothing wrong with having accessor methods -- sometimes you do need to actually retrieve the value. But by making those accessors methods instead of just exposing fields directly, you are implementing information hiding: users of your class don't need to know what the internal state looks like to be able to use it or get data from it.
Basically, in Java (or in any object-oriented language) classes are nouns, and methods are verbs. If you write classes that don't have any verbs, then you're programming in the kingdom of nouns.
Encapsulation allows your object to make guarantees (part of an object's contract), by giving the object control over its own data, which happens to make debugging considerably easier. Consider this class:
public class TravelRoute {
public int distance = 1000;
public int travelSpeed = 60;
public int calculateTravelTime() {
return distance / travelSpeed;
}
}
Any other code is free to set travelSpeed to zero, which will cause all future calls to the calculateTravelTime method to fail. Worse, you will have no way to know who set it to zero, so debugging the problem is going to take a long time.
However, with encapsulation, the class has total control over the value, and can guarantee that it is always valid:
public class TravelRoute {
private int distance = 1000;
private int travelSpeed = 60;
/**
* This is GUARANTEED to return a positive value.
*/
public int getTravelSpeed() {
return travelSpeed;
}
/**
* Sets this instance's travel speed.
*
* #throws IllegalArgumentException if argument is not positive
*/
public void setTravelSpeed(int newSpeed) {
if (newSpeed <= 0) {
throw new IllegalArgumentException("Argument must be positive");
}
this.travelSpeed = newSpeed;
}
public int calculateTravelTime() {
return distance / travelSpeed;
}
}
Now it is absolutely impossible for any outside code to place the object in an invalid state. If anyone tries to do so, the resulting IllegalArgumentException will provide you with an informative stack trace that will immediately expose the culprit.
As a bonus, all other code which uses this class no longer needs to do any checks for its validity, because the object itself can already guarantee that validity. This makes overall development much faster for everyone.

Categories

Resources