I've made some new warning settings in eclipse. With these new settings I'm facing a strange warning. After reading I got to know what it is but couldn't find a way to remove it.
Here is my problem with the sample code
public class Test {
private String testString;
public void performAction() {
new Thread( new Runnable() {
#Override
public void run() {
testString = "initialize"; // **
}
});
}
}
The line with ** gives me a warning in eclipse
Read access to enclosing field Test.testString is emulated by a synthetic accessor method.
Increasing its visibility will improve your performance.
Problem is, I don't want to change the access modifier of testString.
Also, don't want to create a getter for it.
What change should be done?
More descriptive example
public class Synthetic
{
private JButton testButton;
public Synthetic()
{
testButton = new JButton("Run");
testButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
/* Sample code */
if( testButton.getText().equals("Pause") ) {
resetButton(); // **
} else if( testButton.getText().equals("Run") ) {
testButton.setText("Pause"); // **
}
}
}
);
}
public void reset() {
//Some operations
resetButton();
}
private void resetButton() {
testButton.setText("Run");
}
}
Lines with ** gives me the same warning.
What is a "synthetic" method?
Starting from the Method class (and it's parent, Member) we learn that synthetic members are "introduced by the compiler", and that JLS §13.1 will tell us more. It notes:
A construct emitted by a Java compiler must be marked as synthetic if it does not correspond to a construct declared explicitly or implicitly in source code
Since this section is discussing binary compatibility the JVMS is also worth referencing, and JVMS §4.7.8 adds a little more context:
A class member that does not appear in the source code must be marked using a Synthetic attribute, or else it must have its ACC_SYNTHETIC flag set. The only exceptions to this requirement are compiler-generated methods which are not considered implementation artifacts....
The Synthetic attribute was introduced in JDK 1.1 to support nested classes and interfaces.
In other words, "synthetic" methods are an implementation artifact that the Java compiler introduces in order to support language features that the JVM itself does not support.
What's the problem?
You're running into one such case; you're attempting to access a private field of a class from an anonymous inner class. The Java language permits this but the JVM doesn't support it, and so the Java compiler generates a synthetic method that exposes the private field to the inner class. This is safe because the compiler doesn't allow any other classes to call this method, however it does introduce two (small) issues:
Additional methods are being declared. This shouldn't be a problem for the vast majority of use cases, but if you're working in a constrained environment like Android and are generating a lot of these synthetic methods you may run into issues.
Access to this field is done indirectly through the synthetic method, rather than directly. This too shouldn't be a problem except for highly performance-sensitive use cases. If you wouldn't want to use a getter method here for performance reasons, you wouldn't want a synthetic getter method either. This is rarely an issue in practice.
In short, they're really not bad. Unless you have a concrete reason to avoid synthetic methods (i.e. you've determined conclusively they are a bottleneck in your application) you should just let the compiler generate them as it sees fit. Consider turning off the Eclipse warning if it's going to bother you.
What should I do about them?
If you really want to prevent the compiler from generating synthetic methods you have a couple of options:
Option 1: Change the permissions
Package-private or protected fields are accessible to inner classes directly. Especially for something like a Swing application this ought to be fine. But you say you want to avoid this, so on we go.
Option 2: Create a getter
Leave your fields alone, but explicitly create a protected or public getter, and use that instead. This is essentially what the compiler ends up doing for you automatically, but now you have direct control over the method's behavior.
Option 3: Use a local variable and share the reference with both classes
This is more code but it's my personal favorite since you're making the relationship between the inner and outer class explicit.
public Synthetic() {
// Create final local instance - will be reachable by the inner class
final JButton testButton = new JButton("Run");
testButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ae) {
/* Sample code */
if( testButton.getText().equals("Pause") ) {
resetButton();
} else if( testButton.getText().equals("Run") ) {
testButton.setText("Pause");
}
}
});
// associate same instance with outer class - this.testButton can be final too
this.testButton = testButton;
}
This isn't always actually what you want to do. For instance if testButton can change to point to a different object later, you'll need to rebuild your ActionListener again (though that's also nicely more explicit, so arguably this is a feature), but I consider it the option that most clearly demonstrates its intent.
Aside on thread-safety
Your example Test class is not thread-safe - testString is being set in a separate Thread but you're not synchronizing on that assignment. Marking testString as volatile would be sufficient to ensure all threads see the update. The Synthetic example doesn't have this problem since testButton is only set in the constructor, but since that's the case it would be advisable to mark testButton as final.
In your second example it is not necessary to access testButton directly; you can access it by retrieving the source of the action event.
For the resetButton() method you can add an argument to pass the object to act upon, if you've done that it is not such a big problem lowering its access restrictions.
Given the context (you assign to the variable once as part of a fairly expensive operation), I don't think you need to do anything.
I think the problem is that you are setting a String on the parent class. This will suffer in performance because the Thread needs to look up to see where that variable is again. I think a cleaner approach is using Callable which returns a String and then do .get() or something that returns the result. After getting the result you can set the data back on to the parent class.
The idea is you want to make sure the Thread only does one thing and only one thing instead of setting variables on other classes. This is a cleaner approach and probably faster because the inner Thread doesn't access anything outside of itself. Which mean less locking. :)
This is one of the rare cases where Java's default visibility (also called "package private") is of use.
public class Test {
/* no private */ String testString;
public void performAction() {
new Thread( new Runnable() {
#Override
public void run() {
testString = "initialize"; // **
}
});
}
}
This will do the following:
testString is now available to all classes in the same package as the outer class (Test).
As inner classes are actually generated as OuterClassPackage.OuterClassName$InnerClassName, they also reside in the same package. They can therefore access this field directly.
In contrast to making this field protected, the default visibility will not make this field available to subclasses (except when they are in the same package of course). You therefore don't pollute your API for external users.
When using private, javac will instead generate a synthetic accessor, which itself is just a getter method with Java's default visibility as well. So it basically does the same thing, except with a minimal overhead of an additional method.
Related
As succinctly described here, overriding private methods in Java is invalid because a parent class's private methods are "automatically final, and hidden from the derived class". My question is largely academic.
How is it not a violation of encapsulation to not allow a parent's private method to be "overridden" (ie, implemented independently, with the same signature, in a child class)? A parent's private method cannot be accessed or inherited by a child class, in line with principles of encapsulation. It is hidden.
So, why should the child class be restricted from implementing its own method with the same name/signature? Is there a good theoretical foundation for this, or is this just a pragmatic solution of some sort? Do other languages (C++ or C#) have different rules on this?
You can't override a private method, but you can introduce one in a derived class without a problem. This compiles fine:
class Base
{
private void foo()
{
}
}
class Child extends Base
{
private void foo()
{
}
}
Note that if you try to apply the #Override annotation to Child.foo() you'll get a compile-time error. So long as you have your compiler/IDE set to give you warnings or errors if you're missing an #Override annotation, all should be well. Admittedly I prefer the C# approach of override being a keyword, but it was obviously too late to do that in Java.
As for C#'s handling of "overriding" a private method - a private method can't be virtual in the first place, but you can certainly introduce a new private method with the same name as a private method in the base class.
Well, allowing private methods to be overwritten will either cause a leak of encapsulation or a security risk. If we assume that it were possible, then we’d get the following situation:
Let's say that there's a private method boolean hasCredentials() then an extended class could simply override it like this:
boolean hasCredentials() { return true; }
thus breaking the security check.
The only way for the original class to prevent this would be to declare its method final. But now, this is leaks implementation information through the encapsulation, because a derived class now cannot create a method hasCredentials any more – it would clash with the one defined in the base class.
That’s bad: lets say this method doesn’t exist at first in Base. Now, an implementor can legitimately derive a class Derived and give it a method hasCredentials which works as expected.
But now, a new version of the original Base class is released. Its public interface doesn’t change (and neither do its invariants) so we must expect that it doesn’t break existing code. Only it does, because now there’s a name clash with a method in a derived class.
I think the question stems from a misunderstanding:
How is it /not/ a violation of encapsulation to not allow a parent's private method to be "overridden" (ie, implemented independently, with the same signature, in a child class)
The text inside the parentheses is the opposite of the text before it. Java does allow you to “independently implement [a private method], with the same signature, in a child class”. Not allowing this would violate encapsulation, as I’ve explained above.
But “to not allow a parent's private method to be "overridden"” is something different, and necessary to ensure encapsulation.
"Do other languages (C++ or C#) have different rules on this?"
Well, C++ has different rules: the static or dynamic member function binding process and the access privileges enforcements are orthogonal.
Giving a member function the private access privilege modifier means that this function can only be called by its declaring class, not by others (not even the derived classes). When you declare a private member function as virtual, even pure virtual (virtual void foo() = 0;), you allow the base class to benefit from specialization while still enforcing the access privileges.
When it comes to virtual member functions, access privileges tells you what you are supposed to do:
private virtual means that you are allowed to specialize the behavior but the invocation of the member function is made by the base class, surely in a controlled fashion
protected virtual means that you should / must invoke the upper class version of the member function when overriding it
So, in C++, access privilege and virtualness are independent of each other. Determining whether the function is to be statically or dynamically bound is the last step in resolving a function call.
Finally, the Template Method design pattern should be preferred over public virtual member functions.
Reference: Conversations: Virtually Yours
The article gives a practical use of a private virtual member function.
ISO/IEC 14882-2003 §3.4.1
Name lookup may associate more than one declaration with a name if it finds the name to be a function name; the declarations are said to form a set of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded. The access rules (clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name’s declaration used further in expression processing (clause 5).
ISO/IEC 14882-2003 §5.2.2
The function called in a member function call is normally selected according to the static type of the object expression (clause 10), but if that function isvirtualand is not specified using aqualified-idthen the function actually called will be the final overrider (10.3) of the selected function in the dynamic type of the object expression [Note: the dynamic type is the type of the object pointed or referred to by the current value of the object expression.
A parent's private method cannot be accessed or inherited by a child class, inline with principles of encapsulation. It is hidden.
So, why should the child class be
restricted from implementing its own
method with the same name/signature?
There is no such restriction. You can do that without any problems, it's just not called "overriding".
Overridden methods are subject to dynamic dispatch, i.e. the method that is actually called is selected at runtime depending on the actual type of the object it's called on. With private method, that does not happen (and should not, as per your first statement). And that's what is meant by the statement "private methods can't be overridden".
I think you're misinterpreting what that post says. It's not saying that the child class is "restricted from implementing its own method with the same name/signature."
Here's the code, slightly edited:
public class PrivateOverride {
private static Test monitor = new Test();
private void f() {
System.out.println("private f()");
}
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
});
}
}
class Derived extends PrivateOverride {
public void f() {
System.out.println("public f()");
}
}
And the quote:
You might reasonably expect the output to be “public f( )”,
The reason for that quote is that the variable po actually holds an instance of Derived. However, since the method is defined as private, the compiler actually looks at the type of the variable, rather than the type of the object. And it translates the method call into invokespecial (I think that's the right opcode, haven't checked JVM spec) rather than invokeinstance.
It seems to be a matter of choice and definition. The reason you can't do this in java is because the specification says so, but the question were more why the specification says so.
The fact that C++ allows this (even if we use virtual keyword to force dynamic dispatch) shows that there is no inherent reason why you couldn't allow this.
However it seem to be perfectly legal to replace the method:
class B {
private int foo()
{
return 42;
}
public int bar()
{
return foo();
}
}
class D extends B {
private int foo()
{
return 43;
}
public int frob()
{
return foo();
}
}
Seems to compile OK (on my compiler), but the D.foo is not related to B.foo (ie it doesn't override it) - bar() always return 42 (by calling B.foo) and frob() always returns 43 (by calling D.foo) no matter whether called on a B or D instance.
One reason that Java does not allow override the method would be that they didn't like to allow the method to be changed as in Konrad Rudolph's example. Note that C++ differs here as you need to use the "virtual" keyword in order to get dynamic dispatch - by default it hasn't so you can't modify code in base class that relies on the hasCredentials method. The above example also protects against this as the D.foo does not replace calls to foo from B.
When the method is private, it's not visible to its child. So there is no meaning of overriding it.
I apologize for using the term override incorrectly and inconsistent with my description. My description describes the scenario. The following code extends Jon Skeet's example to portray my scenario:
class Base {
public void callFoo() {
foo();
}
private void foo() {
}
}
class Child extends Base {
private void foo() {
}
}
Usage is like the following:
Child c = new Child();
c.callFoo();
The issue I experienced is that the parent foo() method was being called even though, as the code shows, I was calling callFoo() on the child instance variable. I thought I was defining a new private method foo() in Child() which the inherited callFoo() method would call, but I think some of what kdgregory has said may apply to my scenario - possibly due to the way the derived class constructor is calling super(), or perhaps not.
There was no compiler warning in Eclipse and the code did compile. The result was unexpected.
Beyond anything said before, there's a very semantic reason for not allowing private methods to be overridden...THEY'RE PRIVATE!!!
If I write a class, and I indicate that a method is 'private', it should be completely unseeable by the outside world. Nobody should be able access it, override it, or anything else. I simply ought to be able to know that it is MY method exclusively and that nobody else is going to muck with it or depend on it. It could not be considered private if someone could muck with it. I believe that it's that simple really.
A class is defined by what methods it makes available and how they behave. Not how those are implemented internally (e.g. via calls to private methods).
Because encapsulation has to do with behavior and not implementation details, private methods have nothing to do with the idea encapsulation. In a sense, your question makes no sense. It's like asking "How is putting cream in coffee not a violation of encapsulation?"
Presumably the private method is used by something that is public. You can override that. In doing so, you've changed behavior.
I was wondering how to achieve the local static variable in java. I know Java wount support it. But what is the better way to achieve the same? I donot want the other methods in my class to access the variable, but it should retain the value across the invocations of the method.
Can somebody please let me know.
I don't think there is any way to achieve this. Java does not support 'local static' a la C, and there is no way to retrofit this while still keeping your sourcecode "real Java"1.
I donot want the other methods in my class to access the variable, but it should retain the value across the invocations of the method.
The best thing would be to make it an ordinary (private) static, and then just don't access it from other methods. The last bit should be easy ... 'cos you are writing the class.
1 - I suppose you could hack something together that involves preprocessing your code, but that will make all sorts of other things unpleasant. My advice is don't go there: it is not worth the pain.
Rather than trying to actually protect the variable, making the code more obscure and complicated, consider logical protection by comment and placement. I declare normal fields at the start of the class, but a field that should only be accessed from one method just before that method. Include a comment saying it should only be used in the one method:
// i should be used only in f
private int i;
/**
* Documentation for f().
*/
public void f(){
System.out.println(i++);
}
What you want is the ability to constraint intermediate computation results within the relevant method itself. To achieve this, you can refer to the following code example. Suppose you want to maintain a static variable i across multiple calls of m(). Instead of having such a static variable, which is not feasible for Java, you can encapsulate variable i into a field of a class A visible only to m(), create a method f(), and move all your code for m() into f(). You can copy, compile, and run the following code, and see how it works.
public class S {
public void m() {
class A {
int i;
void f() {
System.out.println(i++);
}
}
A a = new A();
a.f();
a.f();
a.f();
}
public static void main(String[] args) {
S s = new S();
s.m();
}
}
In theory, yes - but not in conventional manners.
What I would do to create this:
Create that Object in a totally different class, under the private modifier, with no ability to be accessed directly.
Use a debugging tool, such as the JDI to find that variable in the other class, get it's ObjectReference and manipulate directly or create a new variable which references to that object, and use that variable, which references to the object, in your method.
This is quite complicated, as using the JDI is tough, and you would need to run your program on 2 processes.
If you want to do this, I suggest looking into the JDI, but my honest answer would be to look for another solution.
Based on dacongy's idea of using a method local class I created a simple solution:
public class Main {
public static String m() {
class Statics {
static String staticString;
}
if (Statics.staticString == null)
Statics.staticString = "My lazy static method local variable";
return Statics.staticString;
}
}
Can I do the following?
public Manager(String userName) {
game = new Game(userName);
game.addManager(this);
}
The problem is that I refer to an object (this) in its constructor (before it was actually created).
Although it is legal Java, and in the case you describe (where it is the last line of the constructor) it is a pretty safe thing to do (with certain edge cases exempted), as a practice it is a bad thing to do, and like using goto (in languages that support the keyword) it should be something you think long and hard about. For your case, a better practice would be to make the constructor private, remove the call to addManager and expose a static factory method:
public static Manager createManager(String userName) {
Manager manager = new Manager(userName);
manager.game.addManager(manager);
return manager;
}
I should also point out that that kind of interdependency among classes (the manager knows about the game and the game knows about the manager) is definitely a code smell, and I would be as concerned about the need for that as I would be about passing this from the constructor.
Yes, you can do that, but you should not do that.
The problem is that publishing this while the constructor is still running can produce all kinds of strange side-effects, because some common guarantees don't hold true while the constructor is still running (for example final variables can seem to change their value while the constructor still runs).
This IBM developerWorks article describes the precautions to take when constructing objects and the reasoning behind those precautions. While the article discusses the subject in the light of multi-threading, you can have similar problems in a single-threaded environment when unknown/untrusted code gets a reference to this during construction.
(that last paragraph was "stolen" from one of my earlier answers).
Yup its perfectly legal in Java, however not recommended. See here for more details in the this keyword.
As #James stated, you can, but it is not necessarily something you want to do. If game.addManager tries to access certain properties of the Manager, you can end up trying to access the properties of a Manager that haven't yet been initialized. A better approach is to have an external object call some init method (or some lifecycle method) to add the manager and not do it in the constructor.
see if this helps,it is actually for c/c++ but i think its the same for java:
http://www.gotw.ca/publications/mill13.htm
This technique violates one of java concurrency concepts - safe publication. You should use init() method for this purpose or another technique.
You see, you can initialize some final fields in your constructor (or do some other initialization) after this reference have been escaped. If you pass instance of your object in its constructor to another object then you can get callback during construction. And it can cause inconsistent behavior, NPEs, dead-locks and so on.
Boy, this is not safe! Though valid code, but not good design! Your code allows "this" reference to escape before the object is properly constructed.
Imagine that game.addManager() would invoke some method xxx() on "this" reference.
And we have a subclass of Manager, ChildManager, who overrides method xxx() and this method depends on a field in ChildManager (which isn't initialized when the super constructor reaches its last line of code).
The game.addManager() would see the uninitialized value of the field in ChildManager, which is very very dangerous!
Example code:
public class Manager {
Game game;
public Manager (String userName){
game = new Game(userName);
game.addManager(this);
}
public void xxx(){
}
}
public class ChildManager extends Manager {
String name;
public ChildManager (String username){
super(username);
name = username;
}
public void xxx (){
System.out.println(name);
}
}
public class Game {
public Game (String userName){
}
public void addManager (Manager m){
m.xxx();
}
}
As succinctly described here, overriding private methods in Java is invalid because a parent class's private methods are "automatically final, and hidden from the derived class". My question is largely academic.
How is it not a violation of encapsulation to not allow a parent's private method to be "overridden" (ie, implemented independently, with the same signature, in a child class)? A parent's private method cannot be accessed or inherited by a child class, in line with principles of encapsulation. It is hidden.
So, why should the child class be restricted from implementing its own method with the same name/signature? Is there a good theoretical foundation for this, or is this just a pragmatic solution of some sort? Do other languages (C++ or C#) have different rules on this?
You can't override a private method, but you can introduce one in a derived class without a problem. This compiles fine:
class Base
{
private void foo()
{
}
}
class Child extends Base
{
private void foo()
{
}
}
Note that if you try to apply the #Override annotation to Child.foo() you'll get a compile-time error. So long as you have your compiler/IDE set to give you warnings or errors if you're missing an #Override annotation, all should be well. Admittedly I prefer the C# approach of override being a keyword, but it was obviously too late to do that in Java.
As for C#'s handling of "overriding" a private method - a private method can't be virtual in the first place, but you can certainly introduce a new private method with the same name as a private method in the base class.
Well, allowing private methods to be overwritten will either cause a leak of encapsulation or a security risk. If we assume that it were possible, then we’d get the following situation:
Let's say that there's a private method boolean hasCredentials() then an extended class could simply override it like this:
boolean hasCredentials() { return true; }
thus breaking the security check.
The only way for the original class to prevent this would be to declare its method final. But now, this is leaks implementation information through the encapsulation, because a derived class now cannot create a method hasCredentials any more – it would clash with the one defined in the base class.
That’s bad: lets say this method doesn’t exist at first in Base. Now, an implementor can legitimately derive a class Derived and give it a method hasCredentials which works as expected.
But now, a new version of the original Base class is released. Its public interface doesn’t change (and neither do its invariants) so we must expect that it doesn’t break existing code. Only it does, because now there’s a name clash with a method in a derived class.
I think the question stems from a misunderstanding:
How is it /not/ a violation of encapsulation to not allow a parent's private method to be "overridden" (ie, implemented independently, with the same signature, in a child class)
The text inside the parentheses is the opposite of the text before it. Java does allow you to “independently implement [a private method], with the same signature, in a child class”. Not allowing this would violate encapsulation, as I’ve explained above.
But “to not allow a parent's private method to be "overridden"” is something different, and necessary to ensure encapsulation.
"Do other languages (C++ or C#) have different rules on this?"
Well, C++ has different rules: the static or dynamic member function binding process and the access privileges enforcements are orthogonal.
Giving a member function the private access privilege modifier means that this function can only be called by its declaring class, not by others (not even the derived classes). When you declare a private member function as virtual, even pure virtual (virtual void foo() = 0;), you allow the base class to benefit from specialization while still enforcing the access privileges.
When it comes to virtual member functions, access privileges tells you what you are supposed to do:
private virtual means that you are allowed to specialize the behavior but the invocation of the member function is made by the base class, surely in a controlled fashion
protected virtual means that you should / must invoke the upper class version of the member function when overriding it
So, in C++, access privilege and virtualness are independent of each other. Determining whether the function is to be statically or dynamically bound is the last step in resolving a function call.
Finally, the Template Method design pattern should be preferred over public virtual member functions.
Reference: Conversations: Virtually Yours
The article gives a practical use of a private virtual member function.
ISO/IEC 14882-2003 §3.4.1
Name lookup may associate more than one declaration with a name if it finds the name to be a function name; the declarations are said to form a set of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded. The access rules (clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name’s declaration used further in expression processing (clause 5).
ISO/IEC 14882-2003 §5.2.2
The function called in a member function call is normally selected according to the static type of the object expression (clause 10), but if that function isvirtualand is not specified using aqualified-idthen the function actually called will be the final overrider (10.3) of the selected function in the dynamic type of the object expression [Note: the dynamic type is the type of the object pointed or referred to by the current value of the object expression.
A parent's private method cannot be accessed or inherited by a child class, inline with principles of encapsulation. It is hidden.
So, why should the child class be
restricted from implementing its own
method with the same name/signature?
There is no such restriction. You can do that without any problems, it's just not called "overriding".
Overridden methods are subject to dynamic dispatch, i.e. the method that is actually called is selected at runtime depending on the actual type of the object it's called on. With private method, that does not happen (and should not, as per your first statement). And that's what is meant by the statement "private methods can't be overridden".
I think you're misinterpreting what that post says. It's not saying that the child class is "restricted from implementing its own method with the same name/signature."
Here's the code, slightly edited:
public class PrivateOverride {
private static Test monitor = new Test();
private void f() {
System.out.println("private f()");
}
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
});
}
}
class Derived extends PrivateOverride {
public void f() {
System.out.println("public f()");
}
}
And the quote:
You might reasonably expect the output to be “public f( )”,
The reason for that quote is that the variable po actually holds an instance of Derived. However, since the method is defined as private, the compiler actually looks at the type of the variable, rather than the type of the object. And it translates the method call into invokespecial (I think that's the right opcode, haven't checked JVM spec) rather than invokeinstance.
It seems to be a matter of choice and definition. The reason you can't do this in java is because the specification says so, but the question were more why the specification says so.
The fact that C++ allows this (even if we use virtual keyword to force dynamic dispatch) shows that there is no inherent reason why you couldn't allow this.
However it seem to be perfectly legal to replace the method:
class B {
private int foo()
{
return 42;
}
public int bar()
{
return foo();
}
}
class D extends B {
private int foo()
{
return 43;
}
public int frob()
{
return foo();
}
}
Seems to compile OK (on my compiler), but the D.foo is not related to B.foo (ie it doesn't override it) - bar() always return 42 (by calling B.foo) and frob() always returns 43 (by calling D.foo) no matter whether called on a B or D instance.
One reason that Java does not allow override the method would be that they didn't like to allow the method to be changed as in Konrad Rudolph's example. Note that C++ differs here as you need to use the "virtual" keyword in order to get dynamic dispatch - by default it hasn't so you can't modify code in base class that relies on the hasCredentials method. The above example also protects against this as the D.foo does not replace calls to foo from B.
When the method is private, it's not visible to its child. So there is no meaning of overriding it.
I apologize for using the term override incorrectly and inconsistent with my description. My description describes the scenario. The following code extends Jon Skeet's example to portray my scenario:
class Base {
public void callFoo() {
foo();
}
private void foo() {
}
}
class Child extends Base {
private void foo() {
}
}
Usage is like the following:
Child c = new Child();
c.callFoo();
The issue I experienced is that the parent foo() method was being called even though, as the code shows, I was calling callFoo() on the child instance variable. I thought I was defining a new private method foo() in Child() which the inherited callFoo() method would call, but I think some of what kdgregory has said may apply to my scenario - possibly due to the way the derived class constructor is calling super(), or perhaps not.
There was no compiler warning in Eclipse and the code did compile. The result was unexpected.
Beyond anything said before, there's a very semantic reason for not allowing private methods to be overridden...THEY'RE PRIVATE!!!
If I write a class, and I indicate that a method is 'private', it should be completely unseeable by the outside world. Nobody should be able access it, override it, or anything else. I simply ought to be able to know that it is MY method exclusively and that nobody else is going to muck with it or depend on it. It could not be considered private if someone could muck with it. I believe that it's that simple really.
A class is defined by what methods it makes available and how they behave. Not how those are implemented internally (e.g. via calls to private methods).
Because encapsulation has to do with behavior and not implementation details, private methods have nothing to do with the idea encapsulation. In a sense, your question makes no sense. It's like asking "How is putting cream in coffee not a violation of encapsulation?"
Presumably the private method is used by something that is public. You can override that. In doing so, you've changed behavior.
I've been programming in C# and Java recently and I am curious where the best place is to initialize my class fields.
Should I do it at declaration?:
public class Dice
{
private int topFace = 1;
private Random myRand = new Random();
public void Roll()
{
// ......
}
}
or in a constructor?:
public class Dice
{
private int topFace;
private Random myRand;
public Dice()
{
topFace = 1;
myRand = new Random();
}
public void Roll()
{
// .....
}
}
I'm really curious what some of you veterans think is the best practice. I want to be consistent and stick to one approach.
My rules:
Don't initialize with the default values in declaration (null, false, 0, 0.0…).
Prefer initialization in declaration if you don't have a constructor parameter that changes the value of the field.
If the value of the field changes because of a constructor parameter put the initialization in the constructors.
Be consistent in your practice (the most important rule).
In C# it doesn't matter. The two code samples you give are utterly equivalent. In the first example the C# compiler (or is it the CLR?) will construct an empty constructor and initialise the variables as if they were in the constructor (there's a slight nuance to this that Jon Skeet explains in the comments below).
If there is already a constructor then any initialisation "above" will be moved into the top of it.
In terms of best practice the former is less error prone than the latter as someone could easily add another constructor and forget to chain it.
I think there is one caveat. I once committed such an error: Inside of a derived class, I tried to "initialize at declaration" the fields inherited from an abstract base class. The result was that there existed two sets of fields, one is "base" and another is the newly declared ones, and it cost me quite some time to debug.
The lesson: to initialize inherited fields, you'd do it inside of the constructor.
The semantics of C# differs slightly from Java here. In C# assignment in declaration is performed before calling the superclass constructor. In Java it is done immediately after which allows 'this' to be used (particularly useful for anonymous inner classes), and means that the semantics of the two forms really do match.
If you can, make the fields final.
Assuming the type in your example, definitely prefer to initialize fields in the constructor. The exceptional cases are:
Fields in static classes/methods
Fields typed as static/final/et al
I always think of the field listing at the top of a class as the table of contents (what is contained herein, not how it is used), and the constructor as the introduction. Methods of course are chapters.
In Java, an initializer with the declaration means the field is always initialized the same way, regardless of which constructor is used (if you have more than one) or the parameters of your constructors (if they have arguments), although a constructor might subsequently change the value (if it is not final). So using an initializer with a declaration suggests to a reader that the initialized value is the value that the field has in all cases, regardless of which constructor is used and regardless of the parameters passed to any constructor. Therefore use an initializer with the declaration only if, and always if, the value for all constructed objects is the same.
There are many and various situations.
I just need an empty list
The situation is clear. I just need to prepare my list and prevent an exception from being thrown when someone adds an item to the list.
public class CsvFile
{
private List<CsvRow> lines = new List<CsvRow>();
public CsvFile()
{
}
}
I know the values
I exactly know what values I want to have by default or I need to use some other logic.
public class AdminTeam
{
private List<string> usernames;
public AdminTeam()
{
usernames = new List<string>() {"usernameA", "usernameB"};
}
}
or
public class AdminTeam
{
private List<string> usernames;
public AdminTeam()
{
usernames = GetDefaultUsers(2);
}
}
Empty list with possible values
Sometimes I expect an empty list by default with a possibility of adding values through another constructor.
public class AdminTeam
{
private List<string> usernames = new List<string>();
public AdminTeam()
{
}
public AdminTeam(List<string> admins)
{
admins.ForEach(x => usernames.Add(x));
}
}
What if I told you, it depends?
I in general initialize everything and do it in a consistent way. Yes it's overly explicit but it's also a little easier to maintain.
If we are worried about performance, well then I initialize only what has to be done and place it in the areas it gives the most bang for the buck.
In a real time system, I question if I even need the variable or constant at all.
And in C++ I often do next to no initialization in either place and move it into an Init() function. Why? Well, in C++ if you're initializing something that can throw an exception during object construction you open yourself to memory leaks.
The design of C# suggests that inline initialization is preferred, or it wouldn't be in the language. Any time you can avoid a cross-reference between different places in the code, you're generally better off.
There is also the matter of consistency with static field initialization, which needs to be inline for best performance. The Framework Design Guidelines for Constructor Design say this:
✓ CONSIDER initializing static fields inline rather than explicitly using static constructors, because the runtime is able to optimize the performance of types that don’t have an explicitly defined static constructor.
"Consider" in this context means to do so unless there's a good reason not to. In the case of static initializer fields, a good reason would be if initialization is too complex to be coded inline.
Being consistent is important, but this is the question to ask yourself:
"Do I have a constructor for anything else?"
Typically, I am creating models for data transfers that the class itself does nothing except work as housing for variables.
In these scenarios, I usually don't have any methods or constructors. It would feel silly to me to create a constructor for the exclusive purpose of initializing my lists, especially since I can initialize them in-line with the declaration.
So as many others have said, it depends on your usage. Keep it simple, and don't make anything extra that you don't have to.
Consider the situation where you have more than one constructor. Will the initialization be different for the different constructors? If they will be the same, then why repeat for each constructor? This is in line with kokos statement, but may not be related to parameters. Let's say, for example, you want to keep a flag which shows how the object was created. Then that flag would be initialized differently for different constructors regardless of the constructor parameters. On the other hand, if you repeat the same initialization for each constructor you leave the possibility that you (unintentionally) change the initialization parameter in some of the constructors but not in others. So, the basic concept here is that common code should have a common location and not be potentially repeated in different locations. So I would say always put it in the declaration until you have a specific situation where that no longer works for you.
There is a slight performance benefit to setting the value in the declaration. If you set it in the constructor it is actually being set twice (first to the default value, then reset in the ctor).
When you don't need some logic or error handling:
Initialize class fields at declaration
When you need some logic or error handling:
Initialize class fields in constructor
This works well when the initialization value is available and the
initialization can be put on one line. However, this form of
initialization has limitations because of its simplicity. If
initialization requires some logic (for example, error handling or a
for loop to fill a complex array), simple assignment is inadequate.
Instance variables can be initialized in constructors, where error
handling or other logic can be used.
From https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html .
I normally try the constructor to do nothing but getting the dependencies and initializing the related instance members with them. This will make you life easier if you want to unit test your classes.
If the value you are going to assign to an instance variable does not get influenced by any of the parameters you are going to pass to you constructor then assign it at declaration time.
Not a direct answer to your question about the best practice but an important and related refresher point is that in the case of a generic class definition, either leave it on compiler to initialize with default values or we have to use a special method to initialize fields to their default values (if that is absolute necessary for code readability).
class MyGeneric<T>
{
T data;
//T data = ""; // <-- ERROR
//T data = 0; // <-- ERROR
//T data = null; // <-- ERROR
public MyGeneric()
{
// All of the above errors would be errors here in constructor as well
}
}
And the special method to initialize a generic field to its default value is the following:
class MyGeneric<T>
{
T data = default(T);
public MyGeneric()
{
// The same method can be used here in constructor
}
}
"Prefer initialization in declaration", seems like a good general practice.
Here is an example which cannot be initialized in the declaration so it has to be done in the constructor.
"Error CS0236 A field initializer cannot reference the non-static field, method, or property"
class UserViewModel
{
// Cannot be set here
public ICommand UpdateCommad { get; private set; }
public UserViewModel()
{
UpdateCommad = new GenericCommand(Update_Method); // <== THIS WORKS
}
void Update_Method(object? parameter)
{
}
}