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.
Related
I've been given a coursework assignment where I have to build a prototype hotel booking system, in accordance with the specification, which is as follows:
You will need at least three classes:
Hotel
This should store all the essential information about a hotel,
including a name and some rooms.
Room
This should store the number of beds in a room.
Bed
This should store the size of a bed (i.e. single or double).
I'm totally confused about where to start!
I was under the impression that objects could not be contained within other objects.
For example, let's assume we instantiate a "Hotel" object. How would we then instantiate "Room" objects, and within that object, "Bed" objects?
How are these objects being stored? How do we interact with them indirectly, from another object?
Typically you don't need to nest classes into other classes, which are called inner classes, unless the work that a class takes care of can be chunked into small units that never need to be known outside it's parent class.
It sounds like the concept you want to look into is Composition. It's when an object holds a reference to another object.
public class Room {
private boolean isVacant;
public Room() {
isVacant = true; // The room starts vacant
}
// Pretend there is a way for clients to check in and out of the room
public boolean isVacant() {
return isVacant;
}
}
public class Hotel {
// Using composition, I can make an instance of one class
// available to the methods of another
private Room room101;
public Hotel(Room room101) {
this.room101 = room101;
}
public boolean isRoom101Vacant() {
return room101.isVacant();
}
}
Our hotel may not be very useful having only one room, but this example shows how you can "compose" one object into another. Methods of Hotel can now use methods of it's Room instance known as room101. You will want to think about how your rooms are structured, and how you want to represent it within your Hotel class. A few objects used to store collections of other objects include ArrayList and HashMap.
Edit:
this is a fairly difficult concept to understand before you understand what a class is compared to an instance of that class (an object). In the constructor of my sample Hotel class, I have a variable of type Room called room101. And outside of the constructor is an instance field of the same type and name.
Java will always refer to a variable or reference of the nearest scope. So if I have a method reference called room101, how can I refer to that other one declared outside the constructor, at instance level? That's where this comes in.
public class ThisExample {
// This is a separate variable at the instance level
// Lets call this global in the comments
private int a;
public ThisExample() {
// This is a separate variable in the method level,
// lets call this local in the comments
int a;
a = 5; // our local is now assigned 5
this.a = 10; // Our global is now assigned 10
this.a = a; // our global is now assigned to 5
a = this.a * 2; // our local is now assigned to 10
}
}
In short, this refers to "this" instance of a class. It's a way for an instance of a class to refer to itself as if from the outside. Just like how another object would refer to room101's method as room101.isVacant(). A method in the Room class would similarly do this.isVacant() for the same effect.
And as a final note, if there is only one declaration of a symbol within a class. The this keyword is implied. So Room can call it's own method just as well without it as long as there is no other conflicting symbols of the same name. (This doesn't occur with methods as much as with instance fields/local variables)
Hopefully this helps clear things up a bit!
Your assignment is how to model some real world concepts into code.
It appears that the core of your problem can be stated as a Guest can book a Room.
I don't want to do your work for you, so let me start by asking how you would write that in code? After that, we can address the "Hotel" and "Bed". Is this a major assignment or just a quick question? Your implementation would depend on this.
A rule to learn and apply is:
An action on an object in the real world, becomes a method of that object in an Object Oriented approach.
Unchangeable, constant values should be stored in constants rather than variables for both safer and cleaner code.
The latter doesn't apply to all cases of unchangeable values though: There's the following method that is only called once, on initialising the app that uses the same value of a String twice. The String is only referenced and used inside the method.
My question is: What's the best way of variable/constant definition? Being a simple String in a large application, performance and memory can be neglected, it's more about readability and maintenance.
Is it as variable inside the method:
protected void init() {
final String thestring = "thevalue";
methodA(thestring);
methodB(thestring);
}
or is it as constant on class level (although only used in the method):
private static final String THESTRING = "thevalue";
protected void init() {
methodA(THESTRING);
methodB(THESTRING);
}
or a third, better solution? Please also take into consideration that there can be more, similar methods in the same class.
For me the best solution is to use variable inside the method - because it's internal variable. So other methods shouldn't see it. Consider the encapsulation and clean code, when you try to move this variable on class level you will get a long list of class variables.
Another thing is memory. After method is executed the variables are destroyed. When you define it as a static it will be in your memory all the time.
I can think of three places to put your variable (all final ofc), each has it advantages and disadvantages.
Local variable.
Private static field inside your class.
Public static field inside some Properties class.
1 - Advantages: variable can only be seen inside your method - high code safety. Disadvatages: variable is buried inside a method, can be difficult to find and change.
(I'll skip 2 because it is just compromise between 1 and 3)
3 - Advantages: your field is among other configurable fields, that makes it easy to change your setting. Disadvantages: field is public and everyone can see it (but String is immutable so no one will be able to change it).
Summary: depends on how much you expect you will need to change your variable (e.g. balancing, color changing, ...). If you are sure that this string value is the right one, i wouldn't fear to put that into local variable.
Typically constants are not instance specific. It is thus a better practice to store constants as static variables rather than as member variables. The advantages are:
There is only one allocation of the variable instead of one allocation per object.
You don't need to create an instance variable to access a constant, e.g. PI is declared to be static in the java Math class.
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.
I was watching a tutorial on youtube and the topic was private variables. We usually set variables in java like this:
class hello {
public static void main(String args[]) {
String x;
x = "Hello"
}
}
but in that tutorial, the string type was declared out of the method like this:
class hello {
private String x;
public void apples() {
x = "this is a private variable.";
System.out.println(x);
}
}
As you can see it was not the main method, but i want to ask that do private variables always have to be out of method or what?
I am a beginner so this will be really helpful to know as i don't want to cram up knowledge to prevent confusion and also because it is a matter of fact that people who cram up code never become a good programmer.
do private variables always have to be out of method or what?
That's right. A variable inside a method is a local variable and can not have any access modifiers such as private, public or protected. These modifiers can only be applied to member variables, i.e. variables that are declared in the class scope.
If you think about it, it makes a lot of sense, since local variables can't be accessed by another class anyway. Not even another object of the same class or another method in the same object.
Related question:
What is the difference between a member variable and a local variable?
Cass variables must be declared to be one of the following types:
Public
Protected
Public
In the first example, the variable is local to the function: that is, it's specifically bound to method hello.main().
In that case, it's only accessible within that method function. It's not a class variable, so it doesn't need its access level to be set.
In the second example, the variable is a class variable. When you have a class variable, you can set it to private (can only be accessed by an object of that class), protected (accessed by inherited classes), or public (can be accessed outside of the object). The many methods possible inside the class can then access that class variable.
When you have a variable set inside a class definition, and not inside a method, it is called a "field" or "property" or "attribute." The way you define the accessibility of the field is required since multiple methods within the class can refer to it.
When you have a variable set within any method, it can only be accessed inside of that method, and can't be accessed outside (unless you use a reference pointer or pass it through method arguments).
A private variable in Java is a variable Globally accessible to the class and only to that class (and of course any other methods in the containing class).
A variable declared within a method can be accessed only within the scope of the method. A variable declared inside an if statement is only accessible inside the if statement .... and so on.
Its best to have as little private variable as possible because of performance issues. Lets say you have 100 private variables declared in a class. Your class contains 10 methods and each method utilizes 10 variables. When instantiating an object then your object is created instantiating olso the 100 private variables. If you make you variables local to your methods, then no variable is created on instantiation of the class, and 10 variables are used each time you access a method....
There are also other types of variables in java, to better comprehend you can start from here http://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html
I think what's confusing you is the distinction between a local variable (declared in a method), and a member variable (declared in a class, outside of the class's methods).
A local variable exists just while the method that it's declared in is running. It comes into existence at the point that it's declared, then goes out of scope later, when the next } character occurs (other than those that match { characters that aren't opened yet). This effectively means that the variable disappears in a puff of smoke - it can't be used once it's gone out of scope.
But a member variable lives inside an object. That means it gets created when the object is created, and destroyed when the object is destroyed. So it typically lives for a much longer duration than the local variables do. Member variables can sometimes be used by objects other than the object that they belong to; and there are some quite complex rules around when it's possible to do this.
The private modifier on a member variable just means that it can only be accessed by code that's in the class that the object belongs to.
but i want to ask that do private variables always have to be out of method or what?.
Well, It doesn't make sense actually to make a variable private in a method. Because variables declared in a method are stack variables and they have narrower scope than a private one. As they can be accessed only in the method they are declared in and private variables have scope in the whole class they are declared in.
Any variable created with in a scope ( code block bounded inside { } ) is a local variable of that scope; and not accessible out side the block.
Also private variables is term which comes into picture when you talk about classes and define a member which is not accessible outside class.
I went through local variables and class variables concept.
But I had stuck at a doubt
" Why is it so that we cannot declare local variables as static " ?
For e.g
Suppose we have a play( ) function :
void play( )
{
static int i=5;
System.out.println(i);
}
It gives me error in eclipse : Illegal modifier for parameter i;
I had this doubt because of the following concepts I have read :
Variables inside method : scope is local i.e within that method.
When variable is declared as static , it is present for the entire class i.e not to particular object.
Please could anyone help me out to clarify the concept.
Thanks.
Because the scope of the local variables is limited to the surrounding block. That's why they cannot be referred to (neither statically, nor non-statically), from other classes or methods.
Wikipedia says about static local variables (in C++ for example):
Static local variables are declared inside a function, just like automatic local variables. They have the same scope as normal local variables, differing only in "storage duration": whatever values the function puts into static local variables during one call will still be present when the function is called again.
That doesn't exist in Java. And in my opinion - for the better.
Java doesn't have static variables like C. Instead, since every method has a class (or instance of a class) associated with it, the persistent scoped variables are best stored at that level (e.g., as private or static private fields). The only real difference is that other methods in the same class can refer to them; since all those methods are constrained to a single file anyway, it's not a big problem in practice.
Static members (variables, functions, etc.) serve to allow callers of the class, whether they're within the class or outside of the class, to execute functions and utilize variables without referring to a specific instance of the class. Because of this, the concept of a "static local" doesn't make sense, as there would be no way for a caller outside of the function to refer to the variable (since it's local to that function).
There are some languages (VB.NET, for example), that have a concept of "static" local variables, though the term "static" is inconsistently used in this scenario; VB.NET static local variables are more like hidden instance variables, where subsequent calls on the same instance will have the previous value intact. For example
Public Class Foo
Public Sub Bar()
Static i As Integer
i = i + 1
Console.WriteLine(i)
End Sub
End Class
...
Dim f As New Foo()
Dim f2 as New Foo()
f.Bar() // Prints "1"
f.Bar() // Prints "2"
f2.Bar() // Prints "1"
So, as you can see, the keyword "static" is not used in the conventional OO meaning here, as it's still specific to a particular instance of Foo.
Because this behavior can be confusing (or, at the very least, unintuitive), other languages like Java and C# are less flexible when it comes to variable declarations. Depending on how you want it to behave, you should declare your variable either as an instance variable or a static/class variable:
If you'd like the variable to exist beyond the scope of the function but be particular to a single instance of the class (like VB.NET does), then create an instance variable:
public class Foo
{
private int bar;
public void Bar()
{
bar++;
System.out.println(bar);
}
}
If you want it to be accessible to all instances of the class (or even without an instance), make it static:
public class Foo
{
private static int bar;
public static void Bar()
{
bar++;
System.out.println(bar);
}
}
(Note that I made Bar() static in the last example, but there is no reason that it has to be.)