I am new to programming. I am learning Java now, there is something I am not really sure, that the use of private. Why programmer set the variable as private then write , getter and setter to access it. Why not put everything in public since we use it anyway.
public class BadOO {
public int size;
public int weight;
...
}
public class ExploitBadOO {
public static void main (String [] args) {
BadOO b = new BadOO();
b.size = -5; // Legal but bad!!
}
}
I found some code like this, and i saw the comment legal but bad. I don't understand why, please explain me.
The most important reason is to hide the internal implementation details of your class. If you prevent programmers from relying on those details, you can safely modify the implementation without worrying that you will break existing code that uses the class.
So by declaring the field private you prevent a user from accessing the variable directly. By providing gettters and setters you control exactly how a user may control the variable.
The main reason to not just make the variable public in the first place is that if you did make it public, you would create more headaches later on.
For example, one programmer writes public getters and setters around a private member variable. Three months later, he needs to verify that the variable is never "set" to null. He adds in a check in the "setFoo(...)" method, and all attempts to set the variable will then be checked for "setting it to null". Case closed, and with little effort.
Another programmer realizes that putting in public getters and setters around a private member variable is violating the spirit of encapsulation, he sees the futility of the methods and decides to just make the member variable public. Perhaps this gains a bit of a performance boost, or perhaps the programmer just wants to "write it as it is used". Three months later, he needs to verify that the variable is never "set" to null. He scans every access to the variable, effectively searching through the entire code base, including all code that might be accessing the variable via reflection. This includes all 3rd party libraries which has extended his code, and all newly written modules which used his code after it was written. He then either modifies all calls to guarantee that the variable is never set to null. The case is never closed, because he can't effectively find all accesses to the exposed member, nor does he have access to all 3rd party source code. With imperfect knowledge of newly written modules, the survey is guaranteed to be incomplete. Finally he has no control over the future code which may access the public member, and that code may contain lines which set the member variable to null.
Of course the second programmer could then break all existing code by putting "get" and "set" methods around the variable and making it private, but hey, he could have done that three months earlier and saved himself the explanation of why he needed to break everyone else's code.
Call it what you will, but putting public "get" and "set" methods around a private member variable is defensive programming which has been brought about by many years (i.e. decades) of experience.
Anything public in your class is a contract with the users of the class. As you modify the class, you must maintain the contract. You can add to the contract (new methods, variables, etc.), but you can't remove from it. Idealy you want that contract to be as small as possible. It is useful to make everything private that you can. If you need direct access from package members, make it protected. Only make those things public which are required by your users.
Exposing variables means that you are contracting forever, to have that variable and allow users to modify it. As discussed above, you may find you need to invoke behaviour when a variable is accessed. This can be be done if you only contract for the getter and setter methods.
Many of the early Java classes have contracts which require them to be thread safe. This adds significant overhead in cases where only one thread can access the instance. Newer releases have new classes which duplicate or enhance the functionality but drop the syncronization. Hence StringBuilder was added and in most cases should be used instead of StringBuffer.
Its considered bad mainly because you loose control over who can change the value and what happens when the value changes.
In tiny application written by you for you it won't seem that important but as you start developing for larger and larger applications having control over who changes what and when becomes critical.
Imagine from your example above, you publish library as is, other people use it, then you decide you wanted to calculate another value in your bad class when the size changes ... suddenly the bad00 class has no way of knowing and you can't change it because other people rely on it.
Instead if you had a set method you could extend it to say
void SetSize(int newSize)
{
size = newSize;
DoCalculation;
}
You can extend the functionality without breaking other peoples reliance on you.
I highly recommend the book Effective Java, it contains a lot of useful information about how to write better programs in Java.
Your question is addressed in items 13 and 14 of that book:
Item 13: Minimize the accessibility of classes and members
Item 14: In public classes, use accessor methods, not public fields
You shouldn't allow implementations to alter your records directly. Providing getters and setters means that you have exact control over how variables get assigned or what gets returned, etc. The same thing goes for the code in your constructor. What if the setter does something special when you assign a value to size? This won't happen if you assign it directly.
It's a common pet-peeve of many programmers - Java code with private fields and public accessors and mutators. The effect is as you say, those fields might as well been public.
There are programming languages that voice for the other extreme, too. Look at Python; just about everything is public, to some extent.
These are different coding practices and a common thing programmers deal with every day. But in Java, here's my rule of thumb:
If the field is used purely as an attribute, both readable and writeable by anyone, make it public.
If the field is used internally only, use private. Provide a getter if you want read access, and provide a setter if you want write access.
There is a special case: sometimes, you want to process extra data when an attribute is accessed. In that case, you would provide both getters and setters, but inside these property functions, you would do more than just return - for example, if you want to track the number of times an attribute is read by other programs during an object's life time.
That's just a brief overview on access levels. If you're interested, also read up on protected access.
This is indeed used to hide the internal implementation. This also helps is providing extra bit of logic on your variables. Say you need to make sure that the value passed for a varable should not be 0/null, you can provide this logic in the set method. Also in the same way you can provide some logic while getting the value, say you have a object variable which is not initialised and you are accessing that object, in this case you cand provide the logic to null check for that object and always return an object.
C# programmers use this equally as much, or maybe more frequently than I see in Java. C# calls it properties where in Java it is accessors/mutators
For me it makes sense to have getter and setter methods to encapsulate the classes so that no class can change the instance variables of another class.
Okay. We are talking about Objects here. The real world objects. If they are not private,the user of your class is allowed to change. What if for a Circle class, and for the radius attribute/property of the Circle class, the user sets value as '0'. It doesn't make sense for a Circle to exist with radius as '0'. You can avoid such mistakes if you make your attributes private and give a setter method and in which and throw an Exception/Error (instructing the user ) that it is not allowed to create a Circle with radisu as '0'. Basically, the objects that are created out of your class - are meant to exist as you wished to have them exist. This is one of the ways to achieve it.
As stated earlier, the reason for making a variable private is to hide it from the outside. But if you make a getter AND a setter then you may as well make the variable itself public. If you find yourself later in a position that you made the wrong choice, then you must refactor your code from using the public variable into using the getter/setter which may not be a problem. But it can be a problem if other code, which you do not control, starts depending on your code. Then such a refactoring will break the other code. If you use getters and setters from the start you will reduce that risk in exchange for a little effort. So it depends on your situation.
It depends on who access these public variables. Most likely, only by people inside your company/team. Then it's trivial to refactor them into getters/setters when necessary. I say in this case, it's better to leave the variables public; unless you are forced to follow the java bean convention.
If you are writing a framework or a library intended for the public, then you shouldn't expose variables. It's impossible for you to change them into getters/setters later.
But the 2nd case is more rare than the first; people apply extremely unreasonable assumptions when it come to software engineer, as if they are not writing code, instead they are carving code in stone. And as if the whole world is watching while you code - in reality, nobody will ever read your code except yourself
Related
This question already has answers here:
Why are getter and setter method important in java? [duplicate]
(6 answers)
Closed 7 years ago.
Encapsulation is hiding the data. I would like to hear some really interesting answers here.
What is the point behind keeping variables as private when we already declare public setter methods for variables?
I understand the usage of encapsulation but when we are making the setters as public what is the point behind keeping the variables as private, we can directly use public access modifiers.
Is it because we do not want others to know the exact way we are storing data or managing data on the back-end?
Is it because we do not want others to know the exact way we are
storing data or managing data on the back-end?
Yes, that's the point. It is related to the concepts of abstraction and information hiding too.
You provide a public setter that when invoked by the class client will have the effect that you have documented. It is none of the client's business how this effect is actually achieved. Are you modifying one of the class attributes? Ok, let the client know that, but not the fact that you are actually modifying a variable. In the future, you could want to modify your class so that instead of a simple backup variable it uses something completely different (a dictionary of attributes? An external service? Whatever!) and the client will not break.
So your setter is an abstraction that you provide to the client for "modify this class attribute". At the same time you are hiding the fact that you are using an internal variable because the client doesn't need to know that fact.
(Note: here I'm using the word "attribute" as a generic concept, not related to any concrete programming language)
I fully agree with Konamiman's answer, but I'd like to add one thing:
There are cases where you really don't want that abstraction. And that's fine.
A simple example I like to use here is a class for a 3-dimensional float vector:
class Vector3f {
public:
float x;
float y;
float z;
};
Could you make those fields private and provide setters instead? Sure, you could. But here you might argue that the class is really just supposed to provide a tuple of floats and you don't want any additional functionality. Thus adding setters would only complicate the class and you'd rather leave the fields public.
Now, you can easily construct scenarios where that might bite you later on. For instance, you might one day get a requirement that Vector3fs are not allowed to store NaNs and should throw an exception if anyone tries to do so. But such a hypothetical future problem should not be enough to justify introducing additional abstractions.
It's your call as a programmer to decide which abstractions make sense for the problem at hand and which ones would only get in your way of getting the job done. Unnecessary abstractions are over-engineering and will hurt your productivity just as much as not abstracting enough.
Bottom line: Don't blindly use setters everywhere just because someone claimed that's good practice. Instead, think about the problem at hand and consider the tradeoffs.
Because by encapsulation we provide single point of access. Suppose you define a variable and its setter as follows
String username;
public void setUsername(String username){
this.username = username;
}
Later you like to add some validation before setting username property. If you are setting the username at 10 places by directly accessing the property then you don't have single point of access and you need to make this change at 10 places. But if you have one setter method then by making a change at one place you can easily achieve the result.
Think about this : I'm representing a real life object, a Lion through a class. I'd do something like this.
class Lion {
public int legs;
}
Now my class is needed by some other developer to create an object and set its legs field. He'd do something like this
Lion jungleKing = new Lion();
jungleKing.legs = 15;
Now the question is, Java won't restrict him to setting any number more than 4 as the number of legs for that object. It's not an error, and it'll run just fine. But it's a logical blunder, and the compiler won't help you there. This way a Lion may have any number of legs.
But if we write the code this way
class Lion {
private int legs;
public void setLegs(int legs){
if(legs > 4){
this.legs = 4;
}
else this.legs = legs;
}
}
Now you won't have any Lion with more than 4 legs because the policy of updating the fields of the class has been defined by the class itself and there's no way anyone not knowing the policy is going to update the legs field because the only way to update the legs field is through the setLegs() method and that method knows the policy of the class.
Although Konamiman's answer is spot on, I'd like to add that, in the particular case of public setters versus directly exposing public fields you are asking, there is another very important distinction to keep in mind apart from information hiding and decoupling implementation from the public surface, or API, of a class; validation.
In a public field scenario, there is no way to validate the field's value when it's modified. In case of a public setter (be it a Foo {get; set;} property or a SetFoo(Foo value)) method you have the possibility to add validation code and launch required side-effects and this way ensure that your class is always in a valid or predictable state.
What if you do want to a range check before assignment? That's one of the cases I use setters and getters
More or less simple and realistic example I encountered in practice is an Options class, which has a lot of setters and getters. At some point you might want to add new option which depends on others or has side effects. Or even replace group of options with Enum. In this case setA function will not just modify a field, but will hide some additional configuration logic. Similarly getA will not just return value of a, but something like config == cStuffSupportingA.
Wikipedia has a good overview of [mutator methods(https://en.wikipedia.org/wiki/Mutator_method), which is what setter methods are and how they work in different languages.
The short version: if you want to introduce validation or other logic that gets executed on object modification it is nice to have a setter to put that logic in. Also you may want to hide how you store things. So, those are reasons for having getters/setters. Similarly, for getters, you might have logic that provides default values or values that are dependent on e.g. configuration for things like Locale, character encoding, etc. There are lots of valid reasons to want to have logic other than getting or setting the instance variable.
Obviously, if you have getters and setteres, you don't want people bypassing them by manipulating the object state directly, which is why you should keep instance variables private.
Other things to consider include whether you actually want your objects to be mutable at all (if not, make fields final), whether you want to make modifying the object state threadsafe with e.g. locks, synchronized, etc.
Setting fields as private documents a powerful fact: these private fields are only directly used within the current class. This helps maintainers by not having to track down field usage. They can reason better on the code by looking at the class and determining that the effects on and from these fields with the class' environment go through public and protected method calls. It limits the exposure surface on the class.
In turn, defining a "setter" for a private field is not about giving it publicity again. It is about declaring another powerful fact: an object belonging to this class has a property that can be modified from the outside. (The terms object and property are used in the sense of a bounded part of the whole and an observable fact about this part, not in the OOP sense)
Why then declare a "setter" on a field when making the field public would suffice? Because declaring a field not only binds a name to a property of the objects of the class, but also commits to use memory storage for this property.
Therefore, if you declare a "private field with a setter", you declare three things:
You declare that the name you gave to the field/setter cluster represents a property of the object which is of interest when the object is seen as a black box.
You declare that the value of this property is modifiable by the environment of the object.
You declare that in this particular concrete class, the property of the object is realized by committing some memory storage to it.
I advocate that you never make your fields private with getters and setters indiscriminately. Fields are for describing storage. Methods are for interactions with the environment. (And the particular case of "getters" and "setters" are for describing properties of interest)
This question already has answers here:
Why are getter and setter method important in java? [duplicate]
(6 answers)
Closed 8 years ago.
If I create a class in Java, I've always been taught that the convention is to make all fields of a class private. If I need to access or change them, I can create an accessor and mutator method. I do understand the importance of private variables, as they help reduce complexity and allow for encapsulation.
What I don't understand is that if I create a public accesor and mutator method, isn't the variable public at that point? Why is it still convention to use private variables in situations where anyone can access them?
I should also note that I understand the important of these methods, but I would like to know why we bother to make the variable private even though we are giving anyone access to it through those methods?
Yes, you're right, it does effectively make the variable public. But there's one important difference, which is that it gives you the ability to change things later on: you can remove the setter if you want, or make it private, without affecting code that reads from the field using the getter.
If you'd just made the variable public, you wouldn't be able to stop writes to the field without also breaking reads from the field.
It has other advantages. You can make the access synchronized if you want to later on, without breaking client code, for instance. In short, it allows lots of modifications later on that wouldn't otherwise be possible without causing lots of breakages in code that uses the class.
And you can add extra logic that logs whenever someone writes to the field, or prevents certain threads from writing, or whatever... you can change the type of a field from a HashMap to a TreeMap if your getter abstracts it away and just returns a Map... etc.
Private fields are considered to be internal to the object. So the outside world doesn't need to know about how the data is stored inside the object. This means you can easily change the internal representation of data of an object while everyone else still uses the same accessors / mutators to do its work.
It's also possible that accessors / mutators perform validation and other steps that are needed internally for the object but that you don't wish to expose to code that uses the object.
You could make all fields public but that limits your ability to change the internal structure of the object later on when a lot of code now depends on a field being named a certain way.
I'm newbie to Java and I'm learning about encapsulation and saw an example where instance variables are declared as private in a class.
http://www.tutorialspoint.com/java/java_encapsulation.htm
I have 2 queries:
Why are instance variables private? Why not public?
What if instance variables are made public and accessed directly? Do we see any constraints?
Can you explain with an example as to what will go wrong in case the instance variables are declared as public in a class in Java?
Instance variables are made private to force the users of those class to use methods to access them.
In most cases there are plain getters and setters but other methods might be used as well.
Using methods would allow you, for instance, to restrict access to read only, i.e. a field might be read but not written, if there's no setter. That would not be possible if the field was public.
Additionally, you might add some checks or conversions for the field access, which would not be possible with plain access to a public field. If a field was public and you'd later like to force all access through some method that performs additional checks etc. You'd have to change all usages of that field. If you make it private, you'd just have to change the access methods later on.
If phone was private:
Consider this case:
class Address {
private String phone;
public void setPhone(String phone) {
this.phone = phone;
}
}
//access:
Address a = new Address();
a.setPhone("001-555-12345");
If we started with the class like this and later it would be required to perform checks on the phoneNumber (e.g. some minimum length, digits only etc.) you'd just have to change the setter:
class Address {
private String phone;
public void setPhone(String phone) {
if( !isValid( phone) ) { //the checks are performed in the isValid(...) method
throw new IllegalArgumentException("please set a valid phone number");
}
this.phone = phone;
}
}
//access:
Address a = new Address();
a.setPhone("001-555-12345"); //access is the same
If phone was public:
Someone could set phone like this and you could not do anything about it:
Address a = new Address();
a.phone="001-555-12345";
If you now want to force the validation checks to be performed you'd have to make it private and whoever wrote the above lines would have to change the second line to this:
a.setPhone("001-555-12345");
Thus you couldn't just add the checks without breaking other code (it wouldn't compile anymore).
Additionally, if you access all fields/properties of a class through methods you keep access consistent and the user would not have to worry about whether the property is stored (i.e. is a instance field) or calculated (there are just methods and no instance fields).
They don't have to be private - but they should be. A field is an implementation detail - so you should keep it private. If you want to allow users to fetch or set its value, you use properties to do so (get and set methods) - this lets you do it safely (e.g. validating input) and also allows you to change the implementation details (e.g. to delegate some of the values to other objects etc) without losing backward compatibility.
First, it is not true that all instance variables are private. Some of them are protected, which still preserves encapsulation.
The general idea of encapsulation is that a class should not expose its internal state. It should only use it for performing its methods. The reason is that each class has a so-called "state space". That is, a set of possible values for its fields. It can control its state space, but if it exposes it, others might put it in an invalid state.
For example, if you have two boolean fields, and the class can function properly only in 3 cases: [false, false], [false, true], and [true, false]. If you make the fields public, another object can set [true, true], not knowing the internal constraints, and the next method called on the original object will trigger unexpected results.
Making instance variables public or private is a design tradeoff the
designer makes when declaring the classes. By making instance
variables public, you expose details of the class implementation,
thereby providing higher efficiency and conciseness of expression at
the possible expense of hindering future maintenance efforts. By
hiding details of the internal implementation of a class, you have the
potential to change the implementation of the class in the future
without breaking any code that uses that class.
Oracle White Paper
Like has been pointed out by several answerers already, instance variables don't have to be private, but they are usually at the very least not made public, in order to preserve encapsulation.
I saw an example in (I think) Clean Code, which very well illustrates this. If I recall correctly, it was a complex number (as in a+bi) type; in any case, something very much like that, I don't have the book handy. It exposed methods to get the value of the real and imaginary parts as well as a method to set the value of the instance. The big benefit of this is that it allows the implementation to be completely replaced without breaking any consumers of the code. For example, complex numbers can be stored on one of two forms: as coordinates on the complex plane (a+bi), or in polar form (φ and |z|). Keeping the internal storage format an implementation detail allows you to change back and forth while still exposing the number on both forms, thus letting the user of the class pick whichever is more convenient for the operation they are currently performing.
In other situations, you may have a set of related fields, such as field x must have certain properties if field y falls inside a given range. A simplistic example would be where x must be in the range y through y+z, for numerical values and some arbitrary value z. By exposing accessors and mutators, you can enforce this relationship between the two values; if you expose the instance variables directly, the invariant falls apart immediately, since you cannot guarantee that someone won't set one but not the other, or set them so that the invariant no longer holds.
Of course, considering reflection, it's still possible to access members you aren't supposed to, but if someone is reflecting your class to access private members, they had better realize that what they are doing may very well break things. If they are using the public interface, they might think everything is fine, and then they end up with nasty bugs because they unknowingly did not fully adhere to the implementation details of your particular implementation.
In traditional Object-Oriented design, a class will encapsulate both data (variables) and behavior (methods). Having private data will give you flexibility as to how the behavior is implemented, so for example, an object could store a list of values and have a getAverage() method that computes and returns the mean of these values. Later on, you could optimize and cache the computed average in the class, but the contract (i.e., the methods) would not need to change.
It has become more popular the past few years (for better or worse) to use anemic data models, where a class is nothing but a bunch of fields and corresponding getters and setters. I would argue that in this design you would be better off with public fields, since the getters and setters provide no real encapsulation, but just fool you into thinking you are doing real OO.
UPDATE: The example given in the link in the question is a perfect example of this degenerate encapsulation. I realize the author is trying to provide a simple example, but in doing so, fails to convey any real benefit of encapsulation (at least not in the example code).
Because if you change the structure of the class (removing fields etc.); it will cause bugs. But if you have a getX() method you can calculate the needed value there (if field was removed).
You have the problem then that the class does not know if something is changed and can't guarantee integrity.
Well keeping fields private has many advantages as suggested above.
Next best level is to keep them package private using java default access level.
Default level avoid cluttering in your own code and prevents clients of your code from setting invalid values.
For user of class
We, who are using ide like eclipse, netbins.....
saw that it suggest us for public method, so if creator of class provide getter and setter for private instance variable you do not have to memorize the name of variable. just write set press ctrl+space you are getting all of setter method created by creator of that class and choose your desired method to set your variable value.
For creator of class
Sometimes you need to specify some logic to set variable value.
"suppose you have an integer variable which should store 0
This question already has answers here:
Is it in an anti-pattern to always use get and set methods to access a class's own member fields? [duplicate]
(11 answers)
Closed 9 years ago.
Usually, in my own projects I use getters and setters for any field access, and I followed to do the same on my job. Some time ago, the tech lead of our project asked me why I was doing that and why is this better than just using fields themselves (with an option of declaring them protected if they needed to be accessed by subclasses). I couldn't come up with a clear answer.
So, are there any reasons to using getters and setters inside a class for class' own fields, or is it better to use fields directly?
The most obvious answer is side effects:
int getCost()
{
if (cost == null) {
calculateCost();
}
return cost;
}
If you need the cost, use getCost(). If you want to see if cost has been calculated, use cost.
If there is any business logic around those values (or there is the potential for such logic), then there is a benefit to using getters and setters even for internal calls.
For example, your setter might do validation on its inputs, and throw an exception rather than store an invalid value. Having all your code use that setter rather than simply setting values directly means that the error is caught at the time it is made rather than a long time later when that value is used. A similar case for a getter is when there is a logical default value, which should be used in case of a null. By using a getter, you can safely write local methods without needing continuous null checks or default options.
That said, if there's no business logic in those methods, and no side effects caused by them, then it's mostly a stylistic thing. It is essentially the responsibility of the class to be internally consistent, and as long as it remains so then it's mostly personal/professional preference whether you access the variables directly or through wrapping methods.
You want to declare them as public getters and setters, and private fields. This means external classes (not subclasses) who want to modify the variables all do so through the setters, and get them through the getters. The benefit of this is that if you want to control how or what condition they get or set them, or want to add information or even print debug, it means you only have to put it in the getters and setters.
There's a really good explanation of the benefits on stackoverflow actually:
In Java, difference between default, public, protected, and private
Of course, only make methods when they're actually needed, and similarly, only public when needed by external classes.
Hope that helps the defense!
This is part of the general question as to why you use getters and setters. Many developers use them without though, as a matter of practice. Personally, I only put in getters/setters if I need to.
I would suggest you do what is clearest/simplest to you.
In general, if I can easily add a getter/setter later should I need it, I won't add it. If it would be difficult to add later (or you have an immediate use for them), I would include them.
Some of us are web developers so, we resort to creating JavaBeans and JavaBeans has its own specification. In the specification, it clearly states:
The class must have a public default constructor (no-argument).
The class properties must be accessible using get, set, is (used for boolean properties instead of get) and other methods.
The class should be serializable.
The reason being, JavaBeans were designed for Reusability where JavaBeans could travel through any Java technologies (e.g. Servlets, JSPs, RMI, Web Services, etc.).
That's my 2cent worth on why we have getters/setters. I mostly create JavaBeans.
Some people think that they should always encapsulate all fields by using setters/getters.
Others think that this practice should not be used at all.
If your class does not have any logic for the fields and just is used as a holder, you can skip using methods and just declare your fields as public. This concept is also called a Data Transfer Object (or Messenger.) But as a rule you should use final attribute for such fields to make your class immutable:
public class TwoTuple<A,B> {
public final A first;
public final B second;
public TwoTuple(A a, B b) { first = a; second = b; }
}
However you must/or it's strongly recommended to use setters/getters:
in web applications sometimes there are requirements to use setters/getters. See POJO/JavaBean objects.
if your class is going to be used in concurrent environment. See Java Concurrency in Practice, Section 3.2:
"Whether another thread actually does something with a published reference doesn't really matter, because the risk of misuse is still present.[7] Once an object escapes, you have to assume that another class or thread may, maliciously or carelessly, misuse it. This is a compelling reason to use encapsulation: it makes it practical to analyze programs for correctness and harder to violate design constraints accidentally"
if you want to add some extra logic when you set/get values you must use setters/getters. Just read about encapsulation and its advantages.
My own opinion always declare fields as "private final" and only then, if needed change these properties.
I have created an anonymous class in which I declare a few variables and methods. My java teacher tells me to make these private. I don't see how changing the modifier makes any difference since these variables and methods are private to the anonymous class anyway, so I prefer to have no modifier at all. Who is right and what makes more sense? See below for example code where I choose no modifier for 'map' and 'convert' rather than making them private.
Collections.sort(list, new Comparator<String>(){
public int compare(String a, String b){
return convert(a).compareTo(convert(b));
}
Map<String, String> map = new HashMap<String, String>();
String convert(String s) {
String u = map.get(s);
if (u == null)
map.put(s, u = s.toUpperCase());
return u;
}
});
I would be tempted to make them private simply for the fact that if you refactor the code and pull the anonymous class out as a standard class (Intellij, for example, can do this at the click of a button), having private fields is what you really want. You won't have to go and rework your classes to match your standard.
Personally I would make them private (and final where possible) anyway - it's just a good habit to be in in general.
To put it another way: if you had to put an access modifier on (if, say, the keyword package was also used as an access modifier) what would you choose? Private, presumably - after all, you don't actually want to grant any other class access, do you?
Now, having decided that private is the most logically appropriate access modifier, I would make that explicit in the code.
Then again, I'd quite possibly not create an anonymous inner class with a member variable anyway - I'd be tempted to turn that into a named nested class instead.
Your professor is right.
Make all class variable private and expose them via properties (if not anonymous).
The general rule of thumb is to keep member data such as variable including your Map object private.
Default modifier is not the same as the private modifier, there're subtle differences.
However, in your case it's more a religious question whether to make convert() default or private. I don't see any advantage in making it private though.
Anyway, your code has a memory leak as the String Cache is never cleared :-P
Also, for even shorter/less code, use the Comparator String.CASE_INSENSITIVE_ORDER:
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
It really doesn't matter, but it's probably a good idea to keep your teacher happy as he/she will be grading you.
I'd say it's a matter of style. You can't access the member map outside out of the anonymous class, but it might be best to define them as private for consistency with other classes.
If this were my code, I would say that if a class is complicated enough to need data members, it might be worth pulling it out into a separate class, in which case I'd certainly make the data members private.
The key point is when you say "I don't see how changing the modifier makes any difference since these variables and methods are private to the anonymous class anyway"... you're assuming a lot about how your class is going to be used. Treat every class like it will be passed around and used in a variety of ways, in other words, use modifiers as appropriate. Besides, it makes the intent of class clear. It's not like Java is a terse language anyway, so you might as well be clear.
I don't see much benefit to marking things private just for the hell of it. It won't really gain you anything and someone reading the code might attach some significance to the choice when there really isn't any.
I would question the need for all this complexity. Take a look at: String.compareToIgnoreCase()
You want these fields to be private, so mark them private.If a member is marked neither public not private then something suspicious is going on. Also mark fields that shouldn't change final. Keeping things standardised means less thinking, or at least less thinking on the irrelevant, and less to change when modifying code.
From a language point of view, the only real difference is that if you have extended a base class in the same package, you have now hidden fields or overridden "package-private" (default access) methods. The members can also be accessed via reflection (without setAccessible) by code in the same package (this can have mobile-code security implications).
difference between default and protected.
protected:
object/method is accessible to all classes that are in the same package, and also accessible to sub/extension classes.
default:
object/method is accessible to all classes that are in the same package.
What is your intention of your object/method and code modifier accordingly.
Do not allow yourself to be confused when you come back to the code after six months because in huge projects you want to know that that object/method is or is not accessed anywhere else.
In three weeks, not just months, you would forget what the intended accessibility of those objects, 101% guaranteed. Then if you had a huge project and you had a hundred modifiers that were not specific and you desperately wanted to update the code, you would be frustrated by the compulsion to run reference check on those 100 objects/methods. May be someone took your jar and found the hidden cookies in them and used them, then you changed your code and broke someone's code.
Code your modifiers according to your intention unless you are either one or more of these:
you have no further desire to work
in large java projects.
you are a
extremely intelligent high
functioning autistic person who has
an indexed memory of every event of
your life and can write a completely functional peer-peer file sharing service
within two weeks on a lap top in a
coffee shop.
you deliberately use it
as another tool to obfuscate your
code.