In Java, I feel that using Private when declaring an attribute and not declaring a Setter method for it gives the same outcome as using Final when declaring the attribute, both allow the variable to stay constant.
If that is the case, what is the benefit of using Final in this scenario?
Even without a setter other methods in the class can change the attribute so it's a completely different concept.
Many would argue it's not a good thing to do (it adds "side effects" to your program) but it's still possible.
Assumed you are talking about variables, the keywords final and private define different characteristics.
The keyword final denies any changes to the variable and throws compilation errors when modified or changed. However, without specifying public or private, with the default package-private access modifier, it could be accessed by other classes in the same package once initialized (text with bold fonts are corrected by #charsofire and #MC Emperor).
On the other hand, the keyword private rejects the idea of being called by other classes, even in the same package. But it could be changed and modified by methods in the same class, even without setter or getter methods.
For example in the same class of the same package:
public class Student {
private int score;
final int id;
public Student(int id, int score) {
this.id = id;
this.score = score;
}
public void modifyGrade(int newScore) {
// Accepted
this.score += newScore;
}
public void modifyID(int id) {
// Rejected
this.id = id;
}
}
And in different class of the same package:
public class School {
public static void main(String[] args) {
Student student = new Student(0, 35);
// Accepted
System.out.println(student.id);
// Rejected
System.out.println(student.score);
// Accepted
student.modifyGrade(29);
// throws exception
student.id = 5;
// Not visible
student.score = 29;
}
}
Hope this answer helps you well,
and many thanks again to both #charsofire and #MC Emperor, who helped to clarify significantly in this answer.
The answer is Encapsulation
Consider this.
public class Point
{
int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
//no getters or setters needed, I can just modify or read x and y directly.
}
public class FinalPoint
{
public final Point point;
public FinalPoint(int x, int y)
{
this.point = new Point(x, y);
}
//no getters needed, I'll just read point since it is public
}
Right now, this FinalPoint has a final Point as an instance field. On the one hand, it means that that instance field cannot be reassigned. However, the fields of that instance field can definitely be reassigned.
For example.
FinalPoint p = new FinalPoint(1, 2);
p.point.x = 4; //I have now modified state! final did not protect us here
The final keyword is powerful, but it does not mean that your data is unchangeable. It only means that that surface level reference is unchangeable - it will force a reference to always point to the same object. That does not stop the object its pointing to from changing it's internal state as much as it wants. The only guarantee final makes is that you always be pointing at the same object.
Which brings us to encapsulation. Encapsulation was created to solve this exact problem and more.
Consider this.
public class EncapsulatedPoint
{
private Point point;
public EncapsulatedPoint(int x, int y)
{
this.point = new Point(x, y);
}
public int getX() { return this.point.x; }
public int getY() { return this.point.y; }
}
Now, because I have encapsulated Point and exposed only the data I can safely expose, I have protected myself from modification. It is impossible to change this object (without using reflection or other hacks the designers are actively removing). It truly is Immutable.
Of course, Encapsulation is not superior to using final. There is a time and a place for both. Knowing when and where allows you to make your software secure.
Private variables will never access from the outside of the class and Final will never change by taking input from the user.
Related
I know that this refers to a current object. But I do not know when I really need to use it. For example, will be there any difference if I use x instead of this.x in some of the methods? May be x will refer to a variable which is local for the considered method? I mean variable which is seen only in this method.
What about this.method()? Can I use it? Should I use it. If I just use method(), will it not be, by default, applied to the current object?
The this keyword is primarily used in three situations. The first and most common is in setter methods to disambiguate variable references. The second is when there is a need to pass the current class instance as an argument to a method of another object. The third is as a way to call alternate constructors from within a constructor.
Case 1: Using this to disambiguate variable references. In Java setter methods, we commonly pass in an argument with the same name as the private member variable we are attempting to set. We then assign the argument x to this.x. This makes it clear that you are assigning the value of the parameter "name" to the instance variable "name".
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
Case 2: Using this as an argument passed to another object.
public class Foo
{
public String useBarMethod() {
Bar theBar = new Bar();
return theBar.barMethod(this);
}
public String getName() {
return "Foo";
}
}
public class Bar
{
public void barMethod(Foo obj) {
obj.getName();
}
}
Case 3: Using this to call alternate constructors. In the comments, trinithis correctly pointed out another common use of this. When you have multiple constructors for a single class, you can use this(arg0, arg1, ...) to call another constructor of your choosing, provided you do so in the first line of your constructor.
class Foo
{
public Foo() {
this("Some default value for bar");
//optional other lines
}
public Foo(String bar) {
// Do something with bar
}
}
I have also seen this used to emphasize the fact that an instance variable is being referenced (sans the need for disambiguation), but that is a rare case in my opinion.
The second important use of this (beside hiding with a local variable as many answers already say) is when accessing an outer instance from a nested non-static class:
public class Outer {
protected int a;
public class Inner {
protected int a;
public int foo(){
return Outer.this.a;
}
public Outer getOuter(){
return Outer.this;
}
}
}
You only need to use this - and most people only use it - when there's an overlapping local variable with the same name. (Setter methods, for example.)
Of course, another good reason to use this is that it causes intellisense to pop up in IDEs :)
The only need to use the this. qualifier is when another variable within the current scope shares the same name and you want to refer to the instance member (like William describes). Apart from that, there's no difference in behavior between x and this.x.
"this" is also useful when calling one constructor from another:
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
There are a lot of good answers, but there is another very minor reason to put this everywhere. If you have tried opening your source codes from a normal text editor (e.g. notepad etc), using this will make it a whole lot clearer to read.
Imagine this:
public class Hello {
private String foo;
// Some 10k lines of codes
private String getStringFromSomewhere() {
// ....
}
// More codes
public class World {
private String bar;
// Another 10k lines of codes
public void doSomething() {
// More codes
foo = "FOO";
// More codes
String s = getStringFromSomewhere();
// More codes
bar = s;
}
}
}
This is very clear to read with any modern IDE, but this will be a total nightmare to read with a regular text editor.
You will struggle to find out where foo resides, until you use the editor's "find" function. Then you will scream at getStringFromSomewhere() for the same reason. Lastly, after you have forgotten what s is, that bar = s is going to give you the final blow.
Compare it to this:
public void doSomething() {
// More codes
Hello.this.foo = "FOO";
// More codes
String s = Hello.this.getStringFromSomewhere();
// More codes
this.bar = s;
}
You know foo is a variable declared in outer class Hello.
You know getStringFromSomewhere() is a method declared in outer class as well.
You know that bar belongs to World class, and s is a local variable declared in that method.
Of course, whenever you design something, you create rules. So while designing your API or project, if your rules include "if someone opens all these source codes with a notepad, he or she should shoot him/herself in the head," then you are totally fine not to do this.
this is useful in the builder pattern.
public class User {
private String firstName;
private String surname;
public User(Builder builder){
firstName = builder.firstName;
surname = builder.surname;
}
public String getFirstName(){
return firstName;
}
public String getSurname(){
return surname;
}
public static class Builder {
private String firstName;
private String surname;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setSurname(String surname) {
this.surname = surname;
return this;
}
public User build(){
return new User(this);
}
}
public static void main(String[] args) {
User.Builder builder = new User.Builder();
User user = builder.setFirstName("John").setSurname("Doe").build();
}
}
Unless you have overlapping variable names, its really just for clarity when you're reading the code.
#William Brendel answer provided three different use cases in nice way.
Use case 1:
Offical java documentation page on this provides same use-cases.
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
It covers two examples :
Using this with a Field and Using this with a Constructor
Use case 2:
Other use case which has not been quoted in this post: this can be used to synchronize the current object in a multi-threaded application to guard critical section of data & methods.
synchronized(this){
// Do some thing.
}
Use case 3:
Implementation of Builder pattern depends on use of this to return the modified object.
Refer to this post
Keeping builder in separate class (fluent interface)
Google turned up a page on the Sun site that discusses this a bit.
You're right about the variable; this can indeed be used to differentiate a method variable from a class field.
private int x;
public void setX(int x) {
this.x=x;
}
However, I really hate that convention. Giving two different variables literally identical names is a recipe for bugs. I much prefer something along the lines of:
private int x;
public void setX(int newX) {
x=newX;
}
Same results, but with no chance of a bug where you accidentally refer to x when you really meant to be referring to x instead.
As to using it with a method, you're right about the effects; you'll get the same results with or without it. Can you use it? Sure. Should you use it? Up to you, but given that I personally think it's pointless verbosity that doesn't add any clarity (unless the code is crammed full of static import statements), I'm not inclined to use it myself.
Following are the ways to use ‘this’ keyword in java :
Using this keyword to refer current class instance variables
Using this() to invoke current class constructor
Using this keyword to return the current class instance
Using this keyword as method parameter
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
when there are two variables one instance variable and other local variable of the same name then we use this. to refer current executing object to avoid the conflict between the names.
this is a reference to the current object. It is used in the constructor to distinguish between the local and the current class variable which have the same name. e.g.:
public class circle {
int x;
circle(int x){
this.x =x;
//class variable =local variable
}
}
this can also be use to call one constructor from another constructor. e.g.:
public class circle {
int x;
circle() {
this(1);
}
circle(int x) {
this.x = x;
}
}
Will be there any difference if I use "x" instead of "this.x" in some of the methods?
Usually not. But it makes a difference sometimes:
class A {
private int i;
public A(int i) {
this.i = i; // this.i can be used to disambiguate the i being referred to
}
}
If I just use "method()", will it not be, by default, applied to the current object?
Yes. But if needed, this.method() clarifies that the call is made by this object.
this does not affect resulting code - it is compilation time operator and the code generated with or without it will be the same. When you have to use it, depends on context. For example you have to use it, as you said, when you have local variable that shadows class variable and you want refer to class variable and not local one.
edit: by "resulting code will be the same" I mean of course, when some variable in local scope doesn't hide the one belonging to class. Thus
class POJO {
protected int i;
public void modify() {
i = 9;
}
public void thisModify() {
this.i = 9;
}
}
resulting code of both methods will be the same. The difference will be if some method declares local variable with the same name
public void m() {
int i;
i = 9; // i refers to variable in method's scope
this.i = 9; // i refers to class variable
}
With respect to William Brendel's posts and dbconfessions question, regarding case 2. Here is an example:
public class Window {
private Window parent;
public Window (Window parent) {
this.parent = parent;
}
public void addSubWindow() {
Window child = new Window(this);
list.add(child);
}
public void printInfo() {
if (parent == null) {
System.out.println("root");
} else {
System.out.println("child");
}
}
}
I've seen this used, when building parent-child relation's with objects. However, please note that it is simplified for the sake of brevity.
To make sure that the current object's members are used. Cases where thread safety is a concern, some applications may change the wrong objects member values, for that reason this should be applied to the member so that the correct object member value is used.
If your object is not concerned with thread safety then there is no reason to specify which object member's value is used.
This is a bit difficult to explain so I wrote up and example to illustrate the concept. In the following example I have a stock class which models the figures that affect a stock simulation program. I also have a MarketModifier class which represents events which would affect the stocks in different ways.
public class ExampleArea
{
public static void main(String cvhfg[])
{
Stock test = new Stock(1f,1f,1f,1f);
MarketModifier worldEvent =
new MarketModifier("Bad publicity",-2.5f,"publicOpinion");
}
}
class MarketModifier
{
public MarketModifier(String name, float modifier, String variable) {
super();
this.name = name;
Modifier = modifier;
this.variable = variable;
}
String name;
float Modifier;
String variable;
}
class Stock
{
public Stock(float value, float integrity, float publicPresence, float publicOpinion) {
super();
this.value = value;
this.integrity = integrity;
this.publicPresence = publicPresence;
this.publicOpinion = publicOpinion;
}
float value;
float integrity;
float publicPresence;
float publicOpinion;
//...other variables...
}
My question is how would I link the marketModifer to the variable in the Stock model (in the example above it is "publicOpinion" set in the "variable" String) without using a string. Strings have the problem of possibly mistyping them, and I would need a switch to identify which variable the modifier was affecting.
I thought of using an enum but I would still need a switch table to check them and I would also have to update the enum values every time a stock has a different variable which could be affected (there could be additional variables in the subclasses of Stock). The other option I thought of was reflection but this solution, though I think it would work, seems overly complicated, and adds more difficulty in reading than it solves.
So again, is there a better way to link the an object to the variable(s) that it affects in another object (maybe some kind of observer/watcher pattern?).
Since you want to avoid reflective approaches, what I can suggest is to use an event listener approach.
So what you basically want to do is to listen for the event when market action is performed and then modify the values in your Stock object.
So you would need an interface like this that your MarketModifier would invoke when it is processed.
Modifier.java
public interface Modifier {
public void modify(Stock taget, float modifier);
}
And this interface's implementations would be able to modify any value(s) in the stock object.
An implementation would look like this:
PublicOpinionModifier.java
public class PublicOpinionModifier implements Modifier {
public void modify(Stock target, float modifier) {
target.setPublicOpinion(target.getPublicOpinion() + modifier);
}
}
After that, you can create your MarketManager class like this:
MarketManager.java
public class MarketManager {
// The name of the event.
private String name = "unkown";
// Modifier value of the event.
private float modifier = 0f;
// The listener to listen for the modifications.
private Modifier modificationListener;
// The target stock object towards which the action is directed.
private Stock target;
/**
* Executes the market event.
*/
public void executeAction() {
modificationListener.modify(target, modifier);
}
}
The MarketManager would have the target object (the Stock object to update) and an implementation of Modifer which would be acting as a listener which would be invoked when the market stuff is going on...
TestMarket.java
public class TestMarket {
public static void main(String[] args) {
Stock stock = new Stock(1f, 3f, 1f, 3f);
MarketManager manager = new MarketManager();
manager.setTarget(stock);
manager.setName("Bad Publicity");
manager.setModifier(-2f);
manager.setModificationListener(new PublicOpinionModifier());
manager.executeAction();
}
}
Neat!
I have uploaded a more clean and elaborated version in my public repo.
I would like to make it so I can put integers defined by when I calling new Objectives(new Runnable(), "name here", int x, int y, int z) but I cant seem to do it. Again, the ints in the ENUMS will be put there when calling a new Objectives and the Location
Here's my code so far:
package me.terturl.com.Objectives;
public enum Objectives {
MECH(new Runnable() {
#Override
public void run() {
}
}, "Mech", Location loc, int x, int y, int z);
private String name;
private Location loc;
private int x;
private int y;
private int z;
public objectives(Runnable run, String name, Location loc, int x, int y, int z) {
this.name = name;
this.loc = loc;
this.x = x;
this.y = y;
this.z = z;
}
public String getName() {
return name;
}
public Location getLoc() {
return loc;
}
}
All enums are constants. You cannot specify parameters for new instances of an enum. Instead, use a class to construct new objects based on the given parameters.
Example of an enum in usage:
enum WeekDay { MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6), SUNDAY(0); public final int id; WeekDay(int id){ this.id = id; } }
Example of a class that may be used for this case:
package me.terturl.com.Objective;
import org.bukkit.Location;
public class Objective {
private String name;
private Location loc;
private int x, y, z;
Objective(Runnable run, String name, Location loc, int x, int y, int z) {
this.name = name;
this.loc = loc;
this.x = x;
this.y = y;
this.z = z;
}
public String getName() { return name; }
public Location getLoc() { return loc; }
}
Edit: All enums implicitly extend java.lang.Enum. Since Java does not support multiple inheritance, an enum cannot extend anything else. Hence, enums will not achieve what you are looking for - Storing details of an objective. Instead use the above class and create a Manager Class to handle your objectives.
However, enums can implement interfaces, when applicable:
interface MajorObjectWrapper{
public Object getMajorObject();
}
enum Utility implements MajorObjectWrapper {
VAULT("Gold"),
//...
LOCK(new Lock());
#Override public Object getMajorObject(){ return obj; }
private Object obj;
Utility(Object obj){ this.obj=obj };
}
{
MajorObjectWrapper wrapper=Utility.VAULT;
System.out.println(wrapper.getMajorObject());
// You will get: "Gold"! :)
}
Thanks to #nrubin29 for citation on implementing interfaces with enums.
Specified by:
http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
PS: Your package declaration makes the absolute path of the class me.terturl.com.Objectives.Objectives. Consider refactoring the package declaration as me.terturl.com or me.terturl.com.objectives. Semantics :)
I don't think an enum is what you're looking for. From the Oracle Java tutorial's enum page here:
An enum type is a special data type that enables for a variable to be a set of predefined constants.
Constants. So making new instances really doesn't make sense. And that's also enforced at the language level. JLS section 8.9.2:
It is a compile-time error if a constructor declaration in an enum declaration is public or protected (§6.6).
In an enum declaration, a constructor declaration with no access modifiers is private.
So there's your first problem. You can't have a public enum constructor.
Second, you're slightly misunderstanding how enum constant constructors work. When you do something like
MECH(...)
You're effectively calling a constructor. And you can't do things like have int x in a constructor call. You're going to have treat it like any other constructor, which means either you get to put a method call there or some other expression that evaluates to something. Your first two parameters were OK, but the rest of them, not so much.
For example, if I wanted to make a new String(), I can't do this:
String s = new String(String putStringHere);
Similar logic applies to your code.
Honestly, I'm a little confused why you're using an enum. Seems to me like a regular old class would do just fine.
(also, probably a typo, but your constructor should be capitalized)
How do I build a copy constructor that receive another point (x,y) and copy its values ?
I decide a signature: public Point1 (Point1 other) , but I don't know what to write in it...
The Point class looks like:
public class Point1
{
private int _x , _y;
public Point1 (Point1 other)
{
...
...
}
//other more constructors here...
}
I tried:
public Point1 (Point1 other)
{
_x = other._x ;
_y = other._y;
}
But I almost sure I can do it better..
thnx
Nope, your attempt of
public Point1(Point1 other)
{
_x = other._x ;
_y = other._y;
}
is absolutely fine... (I've corrected the parameter type.)
I'd be tempted to make _x and _y final, and make the class final, but that's because I like immutable types. Others definitely have different opinions :)
Cloning on an inheritance hierarchy is slightly trickier - each class in the hierarchy has to have a relevant constructor, pass whatever argument it's given to the superclass constructor, and then copy just its own fields. For example:
public class Point2 extends Point1
{
private int _z;
public Point2(Point2 other)
{
super(other);
this._z = other._z;
}
}
That's not too bad on the implementation side, but if you want to faithfully clone a Point2 you need to know it's a Point2 in order to call the right constructor.
Implementing Cloneable allows this to be done a bit more simply, but there are other things to consider around that... basically cloning objects isn't as simple as it might appear :) (I'm sure there's an entry in Effective Java for it. If you don't have a copy, buy one now.)
Although the question is quite old but here is an example of copy constructor
public class CopyConstructor {
private int id;
private String name;
public CopyConstructor(int id, String name) {
super();
this.id = id;
this.name = name;
}
public CopyConstructor(CopyConstructor copy) {
id = copy.id;
name = copy.name;
}
}
Copy constructor is much easier to implement and we don't need to
implement Clonable interface.
The clone method returns object which needs to cast , we don't need to cast copy
constructor.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Property and Encapsulation
NEWB Alert!!
I am starting with Android and Java and I am starting to understand it but I am wondering why I should use getters and setters and not just public variables?
I see many people make a private variable and create a get and set method.
What is the idea here?
Its called encapsulation and the concept is central to object oriented programming. The idea is that you hide the implementation of your class and expose only the contract i.e. hide the how and only expose the what. You hide the variables by making them private and provide public setters-getters and other public methods which the clients invoke to communicate with your class. They are not tied to the actual implementation of the methods or how you store your variables.
For example, suppose you had this class where you stored a phone number as a Long object:
public class ContactInfo {
private Long phoneNo;
public Long getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(Long phoneNo) {
this.phoneNo = phoneNo;
}
}
Since the clients of the class only see the getter/setter, you can easily change the implementation of the class/methods by switching the phone number representation to a PhoneNumber object. Clients of ContactInfo wouldn't get affected at all:
public class ContactInfo {
private PhoneNumber phoneNo;
public Long getPhoneNo() {
return phoneNo.getNumber();
}
public void setPhoneNo(Long phoneNo) {
this.phoneNo = new PhoneNumber(phoneNo);
}
}
public class PhoneNumber {
private Long number;
public PhoneNumber(Long number) {
this.number = number;
}
public Long getNumber() {
return number;
}
}
The OOP concept involved is encapsulation (google it).
Some of the advantages are: you can specify different access level for setters (mutators) and getters (accessors), for example public getter and private setter. Another advantage is that you can add another code other than changing or retrieving the value. For example, you may want to check the validity of the set value, or you want to throw exceptions or raise some events in response to changing the variable to certain value. If you implement these inside an accessor or mutators, you can also change their implementations without changing any code outside of the class.
I believe the idea is "information hiding" http://en.wikipedia.org/wiki/Information_hiding
It also serves to control the access to variables (provides an interface). For example, you can provide a getter but not a setter, so that they may be read but not written. Whereas if everything was public any thing could read and write to the variables.
Also important is any checking/validation need to set a variable. For example you have a String name that is not allowed to be empty but if it is public it could easily be forgotten and set as name = "". If you have a setter such as public boolean setName(String newName) you can check newNames length and return true or false if it passes and is set or not
The concept is called encapsulation.
What it attempts to do is to separate the inner structure of a class from its behaviour.
For example, suppose a class like this
public class Point{
private float x;
private float y;
public float getX(){
return x;
}
public float getY(){
return y;
}
public float distanceToZero2(){
return x*x + y*y
}
public float getAngle(){
//havent considered the x = 0 case.
return atan(y/x);
}
public boolean isInFirstQuad(){
return x>0 && y>0;
}
}
In this case, encapsulation hides the inner structure of the class, and exposes only the operations available to a Point. If you dont like it, you can change its inner structure and mantain its behaviour (for example, changing carthesian coordinates to polar coordinates).
Anyoune who uses this class wont care about it, he /she will be happy that they have a Point class with this functionality.
Asides the encapsulation, you can also control the value get or set to your variable in some cases. For example, you want to validate the value of an age variable which should be >=1
class Person {
private int age = Integer.MIN_VALUE;
public void setAge(int age){
if(age>=1)
this.age = age;
}
public int getAge(){
return age;
}
}