Override accessor in Java - java

Is there any way to override the default accessor for a property of an object in Java?
For example if I call Foo.bar, is there some way to know when the bar property is accessed without using a getter function?

What do you mean by, "without using a getter function"? If you extend Foo and override bar's getter method, and if bar is private, then yes you can find out when it is accessed.
This is one reason why properties should all be private, so that you the programmer have full control over what is seen, by whom, and what can change.

No. Foo should be written like this:
private [type] bar;
public [type] getBar() { return bar; }
This allows you to do things when bar is accessed. If bar is public, then you're out of luck.

If I understand your question,
For example if I call Foo.bar, is there some way to know when the bar property is accessed without using a getter function?
Think about this question. A getter will allow you to add this functionality. If the property is private, this problem goes away as any caller is required to use the appropriate getter call. This is an entrenched Java Bean standard.
It's possible to weave aspects into your code to intercept field access, using Aspect Oriented programming (AOP: AspectJ, for example), however there are caveats to this solution which is beyond the scope of your question, but happy to answer in another one :-)

Related

In Java, is there a better alternative to getter and setter methods?

It is common in Java classes to have lots of getter and setter methods, one each for every data model class variable. I realize that many IDEs will create these for you, but I'm trying to avoid this clutter and not have all these methods in my classes. So, is there any way to access a variable in a read only fashion outside the class (as if it were public final), while retaining write access inside the class or subclass exclusively (as if it were private or protected).
The only pseudo-solution I've come up with is a base class (or interface with default methods) that has a get(String variableName) method which then gets the fields of the class via reflection and returns the appropriate one. The downside is that for that to work, the variables have to be public, so only by convention does it meet my requirements (in that in the extending/implementing class that has the variables I want to access, I only call the get method from outside the class, and don't implement a set method). The main thing I don't like about this is that if a variable name changes, callers of the get methods will not cause compiler errors, since the variable name is just a hardcoded String.
Anyone have a better idea?
Yes - try to design your classes so you don't have getters and setters at all. Typically it's a bad design to have getters and setters on all of your fields because it breaks encapsulation. An exception is the case of Java Beans (where you have a model class/DTO or some class that's mapped to XML/JSON); here you should not mind them because setters and getters are the only methods.
In classes that have logic, inject your dependencies via constructor or directly if you use Spring/CDI and you like it. This is more safe because you won't have objects in inconsistent states; like for example you create an object but forget to call a setter -> NullPointerException. But by using constructors, you avoid the case of forgetting to call the setters.
Of course there might be exceptions, like when setting some optional fields when you don't want all the dependencies in the constructor all the time. This however can be solved with overloading constructors or if the case is more complex the problem can be solved in a more elegant way by using the builder pattern.
See a great article on this: http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html
You may use lombok - to manually avoid getter and setter method. But it create by itself.
The using of lombok significantly reduces a lot number of code. I found it pretty fine and easy to use. But here you may find some pros and cons of using lombok here.
Hope it will help.
Thanks a lot.
Java FX introduced something similar to what you want: ReadOnlyProperty
Might not be exactly what you are looking for, though. In general, I don't think exposing a variable is a good idea.

Proper way to declare field that needs to exist in sub-classes?

Say I have a class Animal and then a bunch of sub-classes that extend Animal. Say I want to have a common field called name that should also exist in each child class. What is the proper way to include and initialize this field in each sub-class?
1) Declare the field in the parent as protected, and then initialize it inside of each sub-class. If I do it this way, is it proper to refer to the field as super.variable or simply variable? Personally to me, using super makes it more obvious that the field is declared in the parent. (This is what I am currently doing)
2) Declare the field in the parent as private and then create getters and setters to access the field
3) Just declare and initialize the same variable in each sub-class
4) Another method I'm missing?
Thanks for the help. I understand this question is fairly basic, but I'm curious of what the most proper style is.
Edit:
I'm not to sure if you guys will see this, but here is a follow up question.
Is there any good way to ensure that the sub-classes initialize the field?
The answer depends on whether you need to control access to that field for correctness (e.g., to make sure that some other field gets updated at the same time). If it's okay for subclasses to twiddle the field directly, then just use protected. If you need to perform additional checks or actions whenever the field is set, you should make it private to the superclass and make the subclass use the setter to ensure your logic is run. You shouldn't duplicate the field if you know that it'll always be needed; if you're not sure, then you should consider using an interface Animal and putting the field on an AbstractAnimal implements Animal.
In Java, you don't use super for anything except to call the superclass's version of a method. Just access protected fields directly; that's what they're there for, and your development environment will keep track of where they're declared if you need to know.
I vote for 2:
Create a private field, and have setters and getters (which can be protected to make them accessible only to subclasses).
Other options if you don't need a setter (just a getter):
4) Abstract getter and leave it up to the subclass how to implement it
5) private final field, set by abstract class constructor, and a getter.
I always make fields protected fields, since this helps debuggability & extensibility, and put public getters & setters on them to make a 'property'.
(Private fields in various open-source libraries, Swing components etc have repeatedly been a hindrance to me when trying to do quite legitimate debugging/ extension engineering. So I'm fairly anti- them.)
If I'm concerned about traceability, where there is possible behaviour or errors involved (such as values being got & cached), I might access the variable in subclasses via the getter.
I always use this.name when writing to variables -- it works well for code clarity, and it simplifies parameter-naming in setters. (Use just name for the parameter & this.name for the field.)
I don't use this when reading variables -- it's the writes I want to be clear about. For collections, I suffix the field with List or map or whatever ie childList -- but the parameter and locals are "children".
I never use super when referring to variables. Super would only make sense to disambiguate inherited & declared variables with the same name, which you can legally do -- but is almost guaranteed to be erroneous for code style, clarity & tends to lead to bugs.
I also like to make most properties mutable -- rather than settable only at construction. This helps if you ever want to use Hibernate, or persist the data. Over-reliance on constructor initialization tends to evolve into difficulties -- large & brittle call-signatures, inability to use the class for partly-formed data or "special value" answers, and order-of-init problems.
I think it depends on the situation. If the name field should be publicly accessible, I would declare the field as private and then make public get/set methods. Sometimes you want to expose fields on the base class as part of the public interface of the derived classes.
If the name field should only be used inside the derived classes I would just go with a protected field.
If you want to be sure that a subclass initializes a field add a parameter in the base class constructor, then initialize the field in the base class using the argument supplied by the derived classes constructor.
I usually using option 2 (private + accessors - protected,not necessary public) to have a chance to customize variable access.
About your edit: Force in constructor name if it is a mandatory requirement
Animal(String name) {
this.name = name;
}
or
String getName() {
if(null == name){
name = initializeName();
}
return name;
}
and make initializeName() abstract

Difference between using a method in a class to return a value and referencing the exact value itself

Let's say I have a separate GUI class that has a public boolean called "guiWait" and also has a boolean method that returns guiWait.
What's the difference between:
while(gui.guiWait)...
and
while(gui.getGuiWait())...
The difference is visibility. When you make guiWait public to be used like the first example, outside callers can modify the value. If you use a method and make the variable private, callers cannot modify the guiWait variable (although they can modify the object it references if it's mutable). Furthermore, if you make a habit of using getters and setters, then later on if you need to add logic to the getting or setting process (such as you need to make the value derived from some other new field), you already have the methods and won't break any caller's code by making the variable private. So it's considered "best practice" to always use getters and setters in Java.
If guiWait is a public boolean, there is no point in having a "getter" method for it. If it were private or protected, then it'd be a different story. The private-getter method is more flexible because you can change the implementation of the "getting" of that variable, and add checks or whatever inside the method. Private getters/setters also make things clearer and establish which things should be seen by other classes and which are only meant to be used inside a single class they are apart of. If you find you do need a getter for a specific member variable (need some kind of verification or checking), which is very common, then it would be inconsistent to do it just for that variable.
The core concept of OOP is encapsulation. The getter and setter methods (eg. your getguiWait() method) are used so that nobody is able to access the internal fields of an object. This way no one else is able to set the internal fields to an inconsistent/abnormal value. By using the "getter" and "setter" methods (and hiding the inner fields by using private), you ensure that anyone willing to set or get a field will have to go through the checks that you have put up. Example Class Cat can have age as its field. In the setter method you would check that the user input value is not negative. If you allow the age field to be public, someone could potentially set it to negative which would make no sense.
Its the pure concept of Data Encapsulation in JAVA.
A language mechanism for restricting access to some of the object's components.
A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.
http://www.tutorialspoint.com/java/java_encapsulation.htm

Java - Global variables vs Global methods

I was looking into a project whit 5000+ classes, then I see this in each class:
private static int foo = 1;
private static void setfoo(int value)
{
foo = value;
}
private static int getfoo()
{
return foo;
}
so, I think why dont use a global variable and set it if anyway is static.
There is a resource use difference between global methods and variables?
Thanks you.
Getters and Setters are useful, if you e.g want to add validation in the future (or add logging, or make access statistics or ...)
If the getter/setter exist, always use them. getFoo and setFoo effectively define a property named "Foo", which is conceptually different from your variable foo. foo is just the variable holding the current value of that property, and could be considered as belonging to the property.
Keep in mind, though, a property doesn't have to just get/set its backing variable. It could also validate the value you pass in before setting it. It could synchronize access to the variable. And/or in the future, a setter might alter the characteristics of some other thing, and the getter could return the current state of that other thing, without even needing the backing variable. By setting the variable directly, you create compatibility issues in the case where the property is/would be changed to do any of that in the future.
If, however, you know that setFoo does (and, in the near future, will still do) nothing other than set a variable named foo, then it'd actually be better to not have a getter/setter. They're not any cleaner, or more readable, and they're certainly not more efficient; a = 3; doStuffWith(a); beats setA(3); doStuffWith(getA()); on all counts. And their absence rids you of the conceptual baggage of a property where you only need a variable. Only add the getter/setter when you need (or definitely will need very soon) the special behavior a property can provide. But once you've added them, use them everywhere.
Both the field and getter and setter are private and static.. This means their intended purpose is to be used within the class only . So if you create it at some all class accessible place(globally accessible) , another public class then also you will have to keep track of the field as in every class it has to be initialized to some value before being used (in ur case its 1 i feel). Also you will have to make this code mutually exclusive to keep it correct all the time( would really make it slow if called 5000 times).. Take your call.. its all upto you..

Elementary Java/OOP uncertainties on fields and instances of a class

In a class, you can create fields within them, as int bar in the following example.
Class foo{
int bar;
foo(int bar){
bar = bar;
}
int getBar() {
return bar;
}
void setBar(int bar) {
bar = bar;
}
}
Every time I create a new foo object in another class, will that particular object (instance of foo) have a bar property that when changed with the setBar(), only impacts that instance and no other instances?
I often see people create getters and setters for properties like bar in the above example. If I feel lazy and I'm just writing code for myself/fun, can I just modify the bar property of any instance of this class by accessing the property FooInstance1.bar = 22; instead of having to write a setter and it will have the same effect as in question 1 (just the instance is changed)?
How does the Java compiler know what method is a constructor? By the fact that it has the same name as the class? Or by the fact that one does not specify a return value in the function header? Perhaps it doesn't even matter what the compiler thinks is a constructor (no syntactic difference between regular function), it could be just a semantic thing that people use to differentiate the meaning of functions.
EDIT: I'm having a hard time selecting a best answer. I learned something new from everyone. Thanks!
1) Yes. That's correct.
2) Yes you can, but the best practice is to use the getter and setter. That way, the author of the class can write special logic for the property that is assured to be executed on the get or set. For example, some properties may be calculated on the fly or a notification is sent to listeners when a property is changed.
3) The constructor is the method with no return value and which has the same name as the class. There can be any number of constructors, but each has to have a unique combination of argument types.
Yes, that is the behavior of member variables, one copy exists for each instance. static variables, on the other hand, are class-level variables, one copy shared by all instances.
It is a good practice to not expose the members directly and provide getters to access them. Public setters are also generally discouraged to have better control on how the object state gets modified. But, yes, you can modify them directly also once you declare them as public.
Yes, constructors are special methods without a return type and the name same as that of the class.
Yes.
Yes, but it's not encouraged. With OO, you're trying to hide information about your instance variables, and provide them access on an as-needed basis. Also, setting the variable to public makes it susceptible to unintentional writes or unprivileged reads.
Java recognizes every method by its signature. A signature is composed of its name and it's argument types. For example, the main method has a signature of main(String[]). Constructors are identified by them having the same case-sensitive name as the class.
As an aside, you may want to use this.bar = bar instead, or rename your incoming parameter entirely. Inside of the constructor, the scope of the bar variable is local to what was passed in, so your instance level bar hasn't been assigned.
Yes. That's exactly how it works.
Yes, you can do that, but you'll have to declare the field as public:
public int bar;
Note that this is generally a bad idea and should be avoided.
Yes, constructors have the same name as the class and no return type.
NOTE:
You should always capitalize the names of classes.
Q1 & Q3 have got good answers. Just have something to add for Q2:
Even if you are writing code for fun, you might be disappointed when you find a couple of functionalities impossible without accessors.
You don't want people to change the value of the field but still have read access to it.
When you set a field value, you may want to provide some validaton mechanism for it. You can do validation inside setters.
If you want to play with Reflection, Serialization, Mock Object, etc, you are expected to have getters and setters.
Just name a few functionalities you might not be able to achieve without accessors. There're many more!

Categories