It's been long time since I've asked a question so forgive my mistakes.
So, I have a code which I don't understand. It's dealing with interface and super/sub class. I even have the answers to it but I just don't know how it got to the answer. My question is that, how would I learn tracing or is there a way I can see which lines are executed first in Eclipse?
For example, does eclipse or any other tool allows the user to actually see which and why the lines are printing?
Here is my code. I Have the correct answer to it but I just don't know how they traced it. Any help would be appreciated.
interface Silly {
public void narf();
public void poit(Silly s);
}
public class Bird implements Silly {
public static void main(String args[]) {
System.out.println("zero");
Silly s = new SillyBird(1);
Silly s2 = new Loony();
s.poit(s2);
s2.poit(s);
System.out.println("zymurgy");
}
public Bird() {
this(0);
System.out.println("zircon");
}
public Bird(int i) {
System.out.println("zanzibar");
}
public void narf() {
System.out.println("zort");
}
public void poit(Silly s) {
s.narf();
}
}
class SillyBird extends Bird {
public SillyBird() {
System.out.println("duchess");
}
public SillyBird(int i) {
super(i);
}
public void narf() {
System.out.println("drum");
super.narf();
}
}
class Loony extends SillyBird {
public Loony() {
System.out.println("stupendous");
}
public void narf() {
System.out.println("snark");
}
}
The output of the above code was:
zero
zanzibar
zanzibar
zircon
duchess
stupendous
snark
drum
zort
zymurgy
As mentioned by #Abra in the comments you can set a breakpoint at the functions you want to have a look at and use the ‚go into‘ operation to see what is going on in the function at execution. The debugger will show you the state of all locals and globals at each step of the execution
Related
Thanks for viewing my question, which I have not successfully found an answer for in my searches/books. I'm learning java by writing a roguelike, but I think this question is more java-related than game-related. Feel free to educate me if I'm wrong.
I have similar classes that I want to each have specific abilities. The abilities are enum singletons with a set of standard method names that I would pass the Actor to - I wanted to avoid implementing methods from an interface in every Actor class, and just really liked the envisioned use of this approach as I go forward. I come from a shell/perl background and can't tell if I'm just not thinking OOP, or if I'm on to something useful and don't have the skills yet to pull it off.
addAbility(String) in StdActor is where it finally broke in this experiment.
Question is - am I doing something wrongheaded here? If not, how could I implement this?
interface for manipulating abilities:
public interface ActorAbility {
// doesn't work, but need something to enable
// instance retrieval for addAbility...
public ActorAbility getInstance();
public void act(Actor actor);
public boolean isTickable();
}
sanitized implementation of interface:
public enum ActorMove implements ActorAbility {
INSTANCE;
private ActorMove() {
}
public ActorAbility getInstance() {
return INSTANCE;
}
public void act(Actor actor) {
log.debug("Move");
}
public boolean isTickable() {
return true;
}
}
sanitized use of the ability. trial and error run amock. addAbility(String) broken, copy/paste from SO and elsewhere. it probably needs to be nuked from orbit.
public class StdActor implements Actor {
private HashSet<ActorAbility> abilities = new HashSet<>();
// this whole method is wrecked
public void addAbility(String ability) {
// Class<? extends ActorAbility> action; // in a maze of twisty passages...
ActorAbility actionInstance = null;
try {
// action = Class.forName("game3.Actors.Abilities." + ability);
actionInstance = ActorAbility.valueOf("game3.Actors.Abilities."
+ ability);
} catch (Exception e) {
e.printStackTrace();
}
this.abilities.add(actionInstance);
}
}
use case:
public class StdCharClass extends StdActor {
public StdCharClass() {
// I like this because it's clean and easily
// changeable
addAbility("ActorMove");
}
}
future planned use:
HashSet<ActorAbility> abilities = actor.getAbilities();
for (ActorAbility ability : abilities) {
if (ability.isTickable()) {
ability.act(actor);
}
}
Thanks!
EDIT:
Thanks for such a quick comment, JB. I tried what you suggested and it appears to do what I was hoping. It appears I was just off in the weeds and needed to be pulled back.
new class:
public enum Ability {
MOVE(ActorMove.INSTANCE), FIGHT(ActorFight.INSTANCE);
private ActorAbility ability;
private Ability(ActorAbility abilityClass) {
this.ability = abilityClass;
}
public ActorAbility getAbility() {
return this.ability;
}
}
StdActor:
public class StdActor implements Actor {
private HashSet<Ability> abilities = new HashSet<>();
public void addAbility(Ability ability) {
this.abilities.add(ability);
}
subclass:
public class StdCharClass extends StdActor {
public StdCharClass() {
addAbility(Ability.MOVE);
}
}
and finally, usage:
HashSet<Ability> abilities = bob.getAbilities();
for (Ability ability : abilities) {
ActorAbility abilityClass = ability.getAbility();
if (abilityClass.isTickable()) {
abilityClass.act(bob);
}
}
output!
12:44:15.835 [main] DEBUG ActorMove - Move
is it possible to add a constant to code added to an object? So if my psudo code below where run then the object in question gained focus what ever value was in ZZZ at the time would be printed out?
public void addStupidListener(JTextField textField, String ZZZ) {
textField.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
System.out.println("selected" + ZZZ);
}
#Override
public void focusLost(FocusEvent e) {
System.out.println("de-selected" + ZZZ);
}
});
}
In general you can capture stack variables in Anonymous classes. Here's an example. I assume what you are trying to do will work.
public class AnonymousTest {
public static void main(String[] args){
Object obj = someObject("Hey world!");
System.out.println(obj);
}
public static Object someObject(String str){
return new Object(){
public String toString(){
return super.toString()+str;
}
};
}
}
Output: stackoverflow.AnonymousTest$1#7f31245aHey world!
No this won't be work. You mixed initialization and execution code. You put a listener for future execution, how it can takes the String when you initializes it. Don't do stuff like this, its very irritating.
the following code in eclipse gives a "}" missing in classbody when in eclipse, but compiles perfectly well from the terminal. Any clues?
package quiz;
public class Session {
static int currentQuestion = 0;
private Sentence[] sentences; // for building questions
private Question[] questions;
public void generateReport(Session publishSession) {
}
public int getRightQuestionCount() {
}
public int getWrongQuestionCount() {
}
public int calculatePercent() {
}
public Question getQuestionAtIdx(int index) {
return questions[index];
}
public Question getPreviousQuestion() {
return getQuestionAtIdx(--currentQuestion);
}
public Question getNextQuestion() {
return getQuestionAtIdx(--currentQuestion);
}
public void setQuestionAtIdx(int index, Question) {
}
}
Toward the end, you're declaring a function with two parameters; for the second parameter you specified the type, but no name. Maybe that's it.
public void setQuestionAtIdx(int index, Question <<missing name>>) {
}
that last method
public void setQuestionAtIdx(int index, Question/*has a missing arguement but only its type*/) {
}
so add
public void setQuestionAtIdx(int index, Question question) {
}
I think the problem is here:
public void setQuestionAtIdx(int index, Question) { }
Question has no identifier.
Eclipse sometimes gets confused. If the code is syntactically correct, try restarting eclipse.
your code as you pasted above will not compile due to several issues, notably missing parameter names and return values as mentioned above.
I have the following scenario where
both testOne() and testTwo calls same callMe() method.
How do I decide inside callMe() method who called callMe().
public void testOne(){
callMe();
}
public void testTwo(){
callMe();
}
public void callMe(){
System.out.println("I was called by following method."+methodName);
}
Any sort of help is appreciated.
Any solution that has you generating a stacktrace and looking at the second frame is one that is going to lead to pain - what you are essentially doing is bypassing the idea of passing what a function needs to it in order for the function to do it's work.
If you need the name of the caller method, then just pass it as a parameter. If you need some other piece of data to decide what to do in the callMe() method, pass it (as a boolean, int, etc.).
It will confuse other developers working on your code why callMe() has what are essentially secret parameters.
public void testOne(){
callMe("testOne");
}
public void testTwo(){
callMe("testTwo");
}
public void callMe(String methodName){
System.out.println("I was called by following method."+methodName);
}
My best answer is to query the stack trace.
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
String previousMethodName = null;
for (int i = 0; (i < stackTrace.length) && (previousMethodName == null); i++)
{
if (stackTrace[i].getMethodName().equals("callMe") && (i < stackTrace.length - 1))
{
previousMethodName = stackTrace[i + 1].getMethodName();
}
}
if (previousMethodName != null)
{
System.out.println("Previous method = " + previousMethodName);
}
sorry, i meant to answer your question and not comment :( so here it is
i think this already answered question may help you out: Get current stack trace in Java
The simplest approach is to use a parameter
public static void testOne(){
callMe("testOne");
}
public static void testTwo(){
callMe("testTwo");
}
public static void callMe(){
System.out.println("I was called by following method."+methodName);
}
However, you can use the call stack.
public static void callMe(){
String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
System.out.println("I was called by following method."+methodName);
}
I'm designing a text-based adventure game for a school progress. I have each "level" set up as a class, and each explorable area (node) as a method within the appropriate class.
What's messing with me is the code to move from one node to another. Because each node is connected to up to four other nodes, I have to repeat an extremely similar block of code in each method.
What I'd prefer to do is include an array of methods at the beginning of each node, like this:
public static void zero()
{
... adjacentNodes[] = {one(), two(), three(), four()};
}
And then send that array to a generic method, and have it send the player to the right node:
public static void move(...[] adjacentNodes, int index)
{
adjacentNodes[index];
}
I simplified my code, but that's the general idea. Is this possible?
Whenever you think of pointer-to-function, you translate to Java by using the Adapter pattern (or a variation). It would be something like this:
public class Node {
...
public void goNorth() { ... }
public void goSouth() { ... }
public void goEast() { ... }
public void goWest() { ... }
interface MoveAction {
void move();
}
private MoveAction[] moveActions = new MoveAction[] {
new MoveAction() { public void move() { goNorth(); } },
new MoveAction() { public void move() { goSouth(); } },
new MoveAction() { public void move() { goEast(); } },
new MoveAction() { public void move() { goWest(); } },
};
public void move(int index) {
moveActions[index].move();
}
}
Just have your nodes be objects that all adhere to the same interface, then you'll be able to call their methods reliably.
Since Java does not have the concept of methods as first-class entities, this is only possible using reflection, which is painful and error-prone.
The best approximation would probably be to have the levels as enums with a per-instance implementation of a method:
public enum Level1 implements Explorable{
ROOM1 {
public void explore() {
// fight monster
}
}, ROOM2 {
public void explore() {
// solve riddle
}
}, ROOM3 {
public void explore() {
// rescue maiden
}
};
}
public interface Explorable{
public abstract void explore();
}
public static void move(Explorable[] adjacentNodes, int index)
{
adjacentNodes[index].explore();
}
However, this is a bit of an abuse of the enum concept. I wouldn't use it for a serious project.
Your design has fundamental flaws. Normal OO design would have each "level" be an object (of Class 'level' or something like it). each 'explorable area' would also be an object, contained within the level object - maybe of class ExplorableArea. The 'explorable areas' can be different kinds, in which case you make them different subclasses of ExplorableArea.
Try thinking about solutions without reflection. It's can be enums, for example.
I arrive late at the party with one possible approach, now you can use java.util.function (link) for this kind of problem.
To literally answer the question, regardless of its correctness, or applicability, here a possible version:
public static void zero()
{
Function<World, World> one = (World start) -> RoomWithMonster.in(start);
Function<World, World> two = (World start) -> EmptyRoom.in(start);
Function<World, World> three = (World start) -> RoomWithMonster.in(start);
Function<World, World> four = (World start) -> Treasure.in(start);
List<Function<World, World>> adjacentNodes = List.of(one, two, three, four);
return adjacentNodes;
}
public static void move(List<Function<World, World>> possibleNodes, int index)
{
World beginning = World.start();
World end = possibleNodes.get(index).apply(beginning);
}
This approach prefer immutability and add a little World class to abstract away the state of the game but still maintaining the question you wanted.
NB: fortunately now the reflection comments are obsolete!
You can use Reflection class to create an array of methods.
http://java.sun.com/developer/technicalArticles/ALT/Reflection/