Using a HashMap from another method? - java

If I had a HashMap such as in the following, how would I utilize it from another method? In this case, from Main?
public class Scratch {
public static void init() {
WordEnums words = new WordEnums();
List<String> bookList = new ArrayList<String>();
for (WordEnums.Book bookValues : WordEnums.Book.values()) {
bookList.add(bookValues.getDefinition());
}
HashMap<String, Object> wordDefinitions = new HashMap<>();
wordDefinitions.put("book", bookList);
}
public static void main(String[] args) {
List<String> book = (List<String>) wordDefinitions.get("book");
book.stream().forEach(s -> {
System.out.print(" ");
System.out.println(s);
});
}
I've tried moving it outside of init, something along the lines of what I could find here
But upon doing so, I get an error and am unable to access bookList within init.
Thanks

You can either define it as a static or create get method and get it through instance of the class it's in.
Java static:
https://www.javatpoint.com/static-keyword-in-java

Something to be aware of:
When you declare a member of a class static, it isn't associated with any instance of the class that you create. Given this information, you really have to think about how you want to structure your program.
If the method signature for init has to remain as you've written, you could make wordDefinitions a static member of your class and access it from init. However, if you do take this approach, be careful when you reference it. Remember that there is only one instance of wordDefinitions. Thus, you can only access it through referencing your class (Scratch) and not an instance of it.

The precise answer to the title question is "you can't". Here is why:
The variable named wordDefinitions does not exist outside of the init method. The scoping rules of Java say that it comes into existence every time you execute init and it no longer exists when init terminates. Thus accessing it from outside init has no meaning.
Similarly for bookList, which is why when you move the declaration of wordDefinitions outside of init, you have no access to bookList.
You would probably benefit from a review of Java's scoping rules. But for now, here's an approximate guide. For any data, you need to decide on its lifetime:
One copy that 'always' exists independent of any instances of the class: declare it static in the class.
A copy for each instance that exists for the lifetime of the instance: declare it non-static in the class (and perhaps initialize it in a constructor).
Data that only exists while a method is executing: declare it in the method body.
Given the above, you can access data "upwards" in the list but not "downwards".
This glosses over the distinction between a variable and the object it refers to, but I'm trying to keep it simple.
For your current problem, if you prefer to have all static methods (which seems to be something that introductory students do - are you taught that way? If so, I don't want to confuse matters by proposing differently) you should move the declaration of wordDefinitions to class scope with a static qualifier. Loading in the book list can still be done in init.

Related

Accessing local variables in the main method via reflection

Just having a play around with Java reflection and I think I'm getting the hang of it for the most part. I understand from this question/answer that, for the most part, I'm limited to static variables. If I have an instance of the class though, I can access non-static variables, which does make sense, I get that much.
Say I have the following two classes:
public class A
{
private static int _staticInt;
public static void main(String[] args)
{
B instanceOfB = new B();
}
}
public class B
{
private int _nonStaticInt;
public Game() {}
}
I understand how to access _staticInt, that's not an issue.
My understanding is that I can get the Field for _nonStaticInt in the same way (i.e. Field f = B.class.getDeclaredField("_nonStaticInt");). From other research (javadocs, trails, etc) I have gathered that I need an instance of B in order to get the value of _nonStaticInt.
So my question; Since main is static, is it possible to access instanceOfB in order to access the value of _nonStaticInt? I don't think it is possible, but I thought it's always best to consult people that are more knowledgable than myself before giving up on the idea.
Since main is static, is it possible to access instanceOfB in order to access the value of _nonStaticInt?
"No." Local variables (being in a static method or not) cannot be accessed with the Java Reflection API. Reflection only works at the type level, not the byte-code level2.
The stated understanding of the linked question is correct; reflection access of a non-static (instance) field logically requires an instance. That is, the issue then isn't about reflecting on the B type, the issue is about obtaining the B instance (which is assigned to a local variable) to reflect upon.
To do this the B instance has to be "bled" somehow - e.g. assigned to a static field or passed as an argument to a method/constructor from main1 - so that it can be used with reflection later as the object who's instance members are to be accessed.
The cleanest approach would probably be to pass the B instance down through the appropriate context (or "DI"), perhaps with the aide of IoC .. and maybe changing the type to avoid the use of reflection entirely.
1 Another possible way to "bleed" the B instance is to attach a debugger and inspect/use the local variable within the main methods executing frame - but this sounds like trying to swat a fly with a club.
2 Even tooling like BCEL/ASM wouldn't immediately help during the execution of the main method. Rather it would be used to deconstruct the method, add in the required hooks/code to "bleed" or use the instance created, and then construct a modified method to execute.
Yes, you can get the value of _nonStaticInt in that same way:
B instanceOfB = new B();
Field f = B.class.getDeclaredField("_nonStaticInt");
// Because the variable is private you need this:
f.setAccessible(true);
Object content = f.get(instanceOfB);
System.out.println(content);
The value will be 0, that is the default value for an int.

JAVA : Accessing static method properly

I am new to JAVA, and I like to try and understand everything.
When accessing a static method "hero.returnHp()" in JAVA, I have the following:
hero Mike = new hero();
Mike.returnHp();
The program runs fine, but I notice that Eclipse has a warning stating, "The static method from the type hero should be accessed in a static way." When I accept the auto-fix, it changes "Mike.returnHp();" to "hero.returnHp();".
So I have two questions:
1) What is the advantage of this?
2) If I created two objects of the same type, how would I specify which one to return when accessing in a static way?
Thanks!
I would first like to point out what the keyword static means.
Static variables only exist once per class – that is, if you create a class with a static variable then all instances of that class will share that one variable. Furthermore, if it’s a public static variable, then anyone can access the variable without having to first create an instance of that class – they just call Hero.staticVariableName;
Static method/functions are stateless. That is, they act only on information (1) provided by arguments passed to the method/function, or (2) in static variables (named above), or (3) that is hard-coded into the method/function (e.g. you create a static function to return “hello” – then “hello” is hard-coded into the function).
The reason why Eclipse wants you to access static methods in a static way is because it lets you and subsequent programmers see that the method you’re accessing is static (this helps to prevent mistakes). The function will run either way you do it, but the correct way to do it is to access static functions in a static way. Remember that if you call a static method, no matter what instance variable you call it from (Tim.returnHp, Jim.returnHp, Mike.returnHp, whatever) you will call the same function from the hero class and you will see the exact same behavior no matter who you call it from.
If you created two objects of the same type then you COULD NOT specify which one to return when accessing in a static way; static functions/methods will refer to the entire Hero class.
Can you explain what you’re trying to do so that we can offer more specific feedback? It’s quite possible that returnHp() shouldn’t be static.
Is that “return hit points”? If it is, then you do NOT want it static because the number of hit points that a hero has is part of the hero’s state, and static methods are stateless. (Think of state like the current condition – alive, dead, wounded, attacking, defending, some combination of the aforementioned, etc.) I would recommend going into the Hero class and changing returnHp to a non-static method.
Now… I know you didn’t ask, but I would like to advise you of something:
Class names (such as Hero) should be capitalized. Instance variable names (such as mike) should be lowercase. This is a widely accepted naming convention and it will increase the readability of your code.
Jeff
A static method is one which belongs to a class but not to an object. In your example above, you have created an object Mike of class hero. The method returnHp() is static, and belongs to the hero class, not the hero objects (such as Mike).
You will likely get an IDE or compiler warning when you reference a static method from an object, because it should never be tied to that object, only to its class.
Based on the method name, I would guess it shouldn't be static.
class hero {
private float hp;
public float returnHp() { // Should NOT be "public static float ..."
return hp;
}
}
The JavaDocs on class members has a brief discussion on statics as well. You may want to check that out.
A static method is completely independent of any instances of the class.
Consider that this works, and does not result in a NullPointerException:
hero Mike = null;
Mike.returnHp();
(by the way, class names should start with a capital, and variable names be lowercased).
Here is another neat example: Being a static method, Thread.sleep always sleeps the current thread, even if you try to call it on another thread instance.
The static method should be called by class name, not through an instance, because otherwise it is very confusing, mostly because there is no dynamic dispatch as static methods cannot be overridden in subclasses:
hero Tim = new superhero(); // superhero extends hero
Tim.returnHp(); // still calls the method in hero, not in superhero
You are getting a compiler warning now, but many people say that this was a design mistake and should be an error.
It is part of the JVM spec.
You don't need to. A static method is common between instances of a class, your confusion arises from thinking it is an instance method.
static means a static way. One reason to use static is you can access it using class directly. that is its benefit. that is why main is always static. The entrance function don't need to create an instance first.
Actually if you search static in google, and understand it deeply. U will know when and why use static.

Java Variables Conventions

I'm confused with variable declarations in Java code.
I read... don't try to use global variables declarations .
Don't use something like this:
package cls;
public class test {
private String var;
public someMethod(){ ... }
}
And use ?
package cls;
public class test {
public someMethod(){
String var = null;
}
}
I don't know which is the correct way....
It totally depends on what you need.
Your first example, however, isn't a global variable--it's an instance variable.
Variables should have as small a scope as possible. This makes code easier to reason about.
Instance variables are central to what OOP is all about--classes (objects) exist to encapsulate object state, and the methods that operate on that state. For example, a Person class would likely have first and last name instance variables:
public class Person {
private String firstName;
private String lastName;
// Plus getters and setters for each.
}
This allows instance methods to access the first and last name variables directly without having to pass them between all the methods that need them.
The second example is a local variable. It's visible only in the method it's declared in. A reference to it may be passed to other methods.
Both are correct. Neither of those are global variables. The first one is a class field. It's unique to each instance of the class that you make. Class fields (ie. variable) stay with the instance of the class until the class itself is deleted.
The second one is a method scope variable. It's only there for temporary purposes to perform the calculations needed for the method to work, and once the code in the method is done, the variable goes away.
You use each for different purposes. For example, if you're writing a Car class, you'd probably have a class field for SteeringWheel and Brake. But if you had a method to calculate the average miles per gallon, you might create a method scoped variable to help perform the calculation.
Java doesn't have global variables. The first variable is class level and maintains the state of class instances and hence exists as long as an instance of the class while the second is a method's local variable that exists only during method's execution. You can use the first variable to store state information that spans multiple method calls. The second variable disappears as soon as the control leaves the method. Also, every time you call the method another variable, accessible by the same local name is created on the stack.
You can't have truly "global" variables in Java the same way as you can in a language such as C. Java forces you to structure your program in an object oriented way.
In your example above, if var is required throughout a whole test object and is important to have stored, then you would use the first example. If var is only required in someMethod and it's not important for a test object to store it then use the second example.
Take note that even with the first example, var is encapsulated within a test object, so it's not really "global" at all, apart from maybe slightly to the member function of test (which is the whole point of instance/member variables).
The closest thing in Java to "global" data is something like:
public class GlobalVars {
public static int globalInt;
}
And you could access globalInt throughout your code as GlobalVars.globalInt, without creating an instance of GlobalVars.

Java: How To Call Non Static Method From Main Method?

I'm learning java and now i've the following problem: I have the main method declared as
public static void main(String[] args) {
..... }
Inside my main method, because it is static I can call ONLY other static method!!! Why ?
For example: I have another class
public class ReportHandler {
private Connection conn;
private PreparedStatement prep;
public void executeBatchInsert() { ....
} }
So in my main class I declare a private ReportHandler rh = new ReportHandler();
But I can't call any method if they aren't static.
Where does this go wrong?
EDIT: sorry, my question is: how to 'design' the app to allow me to call other class from my 'starting point' (the static void main).
You simply need to create an instance of ReportHandler:
ReportHandler rh = new ReportHandler(/* constructor args here */);
rh.executeBatchInsert(); // Having fixed name to follow conventions
The important point of instance methods is that they're meant to be specific to a particular instance of the class... so you'll need to create an instance first. That way the instance will have access to the right connection and prepared statement in your case. Just calling ReportHandler.executeBatchInsert, there isn't enough context.
It's really important that you understand that:
Instance methods (and fields etc) relate to a particular instance
Static methods and fields relate to the type itself, not a particular instance
Once you understand that fundamental difference, it makes sense that you can't call an instance method without creating an instance... For example, it makes sense to ask, "What is the height of that person?" (for a specific person) but it doesn't make sense to ask, "What is the height of Person?" (without specifying a person).
Assuming you're leaning Java from a book or tutorial, you should read up on more examples of static and non-static methods etc - it's a vital distinction to understand, and you'll have all kinds of problems until you've understood it.
Please find answer:
public class Customer {
public static void main(String[] args) {
Customer customer=new Customer();
customer.business();
}
public void business(){
System.out.println("Hi Harry");
}
}
Java is a kind of object-oriented programming, not a procedure programming. So every thing in your code should be manipulating an object.
public static void main is only the entry of your program. It does not involve any object behind.
So what is coding with an object? It is simple, you need to create a particular object/instance, call their methods to change their states, or do other specific function within that object.
e.g. just like
private ReportHandler rh = new ReportHandler();
rh.<function declare in your Report Handler class>
So when you declare a static method, it doesn't associate with your object/instance of your object. And it is also violate with your O-O programming.
static method is usually be called when that function is not related to any object behind.
You can't call a non-static method from a static method, because the definition of "non-static" means something that is associated with an instance of the class. You don't have an instance of the class in a static context.
A static method means that you don't need to invoke the method on an instance. A non-static (instance) method requires that you invoke it on an instance. So think about it: if I have a method changeThisItemToTheColorBlue() and I try to run it from the main method, what instance would it change? It doesn't know. You can run an instance method on an instance, like someItem.changeThisItemToTheColorBlue().
More information at http://en.wikipedia.org/wiki/Method_(computer_programming)#Static_methods.
You can think of a static member function as one that exists without the need for an object to exist. For example, the Integer.parseInt() method from the Integer class is static. When you need to use it, you don't need to create a new Integer object, you simply call it. The same thing for main(). If you need to call a non-static member from it, simply put your main code in a class and then from main create a new object of your newly created class.
You cannot call a non-static method from the main without instance creation, whereas you can simply call a static method.
The main logic behind this is that, whenever you execute a .class file all the static data gets stored in the RAM and however, JVM(java virtual machine) would be creating context of the mentioned class which contains all the static data of the class.
Therefore, it is easy to access the static data from the class without instance creation.The object contains the non-static data
Context is created only once, whereas object can be created any number of times.
context contains methods, variables etc. Whereas, object contains only data.
thus, the an object can access both static and non-static data from the context of the class
Since you want to call a non-static method from main, you just need to create an object of that class consisting non-static method and then you will be able to call the method using objectname.methodname();
But if you write the method as static then you won't need to create object and you will be able to call the method using methodname(); from main. And this will be more efficient as it will take less memory than the object created without static method.
Useful link to understand static keyword
https://www.codeguru.com/java/tij/tij0037.shtml#Heading79

How to modify private static variable through setter method

I have the following variable in a class named Example:
private static int number;
If I wanted to assign the variable a number using an outside class, which would I do?
1) Make the setter method in Example static so I can access it like this:
Example.setNumber(3);
2) or Make the setter method non-static so I create an object of Example to set the number
Example e = new Example()
e.setNumber(3);
What are the differences between the two and which one is the better way?
It is recommendable to use a static method in this case.
Why? Well, if you make it a non-static method, that would lead to the following suprising effect:
Example e1 = new Example();
Example e2 = new Example();
e2.setNumber(3);
e1.setNumber(5);
System.out.println(e2.getNumber()); // surprise! prints 5,
So even though you called the method on e1, e2 is also affected. The corresponding static example is much less surprising:
Example e1 = new Example();
Example e2 = new Example();
Example.setNumber(5);
System.out.println(Example.getNumber()); // prints 5, no surprise...
First of all, you really shouldn't be setting static variables. It's prone to cause problems, and it's generally indicative of bad design. The only times static variables should be used are for thread-safe immutable objects and singletons.
That said, if you absolutely still want to set the value, make it a static method, ince you shouldn't need to instantiate the object in order to set a static value.
The first one would be the correct one. When you access a static method, you use the class name and not an object refrence
If it's a static variable, make the setter static. Having to create an instance just to modify something that belongs to the whole class is both verbose and wasteful.
Please don't use the second option. Creating an instance just for an assignment is a crime:P.
Use the first option or just make the number public, depending on your needs.
The setter of a static variable that do not depends on any instance variables/functions should be also static. So 1).
But beware of creating global variables!
There is no point to creating an instance of a class just to set a static variable on it. I would go with #1. (Although I try to avoid global variables, which is what the static variable is.)
Static member is the same for all instances of class. You can change is either using static or regular setter. But regular setter in this case may confuse user: the naming convention says that setter changes value of field that belongs to specific instance. Therefore you should use the first version: Example.setNumber(3).
Static variables are made static because they are not associated with any particular object.
Both approaches work, but the former is more sensible, because it does not require an arbitrary object to be created and used.
The consensus of other posters is for #1 static method.
I will argue that we can not answer the question with available information. If for example, the setNumber method is necessary to implement an interface then it should be #2 instance method. Tell us where the setNumber method will be used.

Categories