Let's say I have a synchronized method on some class:
abstract class Foo {
public synchronized void foo() { // synchronized!
// ...
};
}
and I overrode it without using the synchronized modifier:
class Bar extends Foo {
#Override
public void foo() { // NOT synchronized!
super.foo();
// ...
}
}
I have a couple of specific question regarding this scenario:
Will the overridden method be implicitly synchronized as well?
If not, will the super-call be synchronized?
If there is no super-call, will anything be synchronized?
Is there a way to force an overriding method to use synchronized (I noticed that abstract method definitions or method definitions inside an interface don't allow the synchronized keyword)?
public synchronized void foo() { // synchronized!
// ...
};
Is essentially the same as:
public void foo() {
synchronized (this) { // synchronized!
// ...
}
};
The latter is more explicit, so I would generally suggest using that form. Or better using a lock that is a private field instead of the "outer" object.
So: 1. No. 2. Yes. 3. No. 4. Mark the method final and call a protected method that may be overridden.
public final void foo() {
synchronized (this) {
fooImpl();
}
};
protected void fooImpl() {
// ...
}
As ever, you may well be better off with delegation rather than subclassing.
Failing to use synchronized when overriding a synchronized method has the potential for causing runtime bugs. As a safeguard, there is an Eclipse checker you can turn on to detect this condition.
The default is "ignore". "Warning" is also a valid choice.
which will produce this message:
Related
Now I am very aware that you can simply do the following:
public static void methodA() {
doSomeOtherStuffHere();
methodB();
}
public static void methodB() {
doStuffHere();
}
But in my scenario, I cannot change the code of method A ( I cannot add the methodB(); ). So is there any way I can detect when method A is called (and then execute method B when it is)?
You can use Aspect Oriented Programming (https://www.baeldung.com/aspectj) to create aspect which will be executed before YourClass.methodB()
In plain Java, you can do this by creating a subclass of the Class (Which owns methodA) and override the method methodA. Write your own Implementation and use the subclass method where ever you need.
in you code you have "doSomeOtherStuff()" method. You could place methodB within it. Here is an example:
public class App{
public static boolean isCalled = true;
public static void main( String[] args ){
starterMethod();
}
public static void methodB() {
System.out.println("Method B started");
}
public static void starterMethod() {
methodB();
}
}
In you example you can call "doOtherStuffHere". You could call methodB within doOtherStuffHere and that method could contain a call to methodB.
If I don't want that a method on my class can be called, I just make it private.
But if I want to allow that method to be overridden, I have to make it protected
Is it possible to have a method on an abstract class that can't be called but can be overridden? (I guess not, but is there any workaround?)
Use case:
abstract class Super {
protected void finalize() {
}
public final void doThings() {
// do stuff
finalize();
}
}
and whoever wanted to extend the class:
class Sub extends Super {
#Override
protected void finalize() {
closeSockets();
alertSomeone();
}
}
But I don't want other classes calling mySub.finalize();
Instead of overwriting a method, the sub-class may provide the super-class with a Runnable which contains the code to be executed. You could do something like this:
public class Super {
private final Runnable subClassCode;
public Super(Runnable finalizeCode) {
subClassCode = finalizeCode;
}
public final void doThings() {
// do stuff
subClassCode.run();
}
}
public class Sub extends Super {
public Sub() {
super(() -> {
// code to be executed in doThings()
});
}
}
You dont need to set the Runnable instance in the constructor. You may also give access to a protected setFinalizeCode(Runnable) method but that method could also be called by other classes within the same package as Super.
my problem is that:
search_text.addModifyListener(new ModifyListener() {
#Override
public void modifyText(ModifyEvent e) {
ArrayList<Object> GPDMvalue = (ArrayList<Object>) multiSortList.getValue();
ArrayList<Map<String, Object>> valueList = getDefaultValue(GPDMvalue);
multiSortList.clear();
if(getGPDMList().size()==0)return;
multiSortList.setDataSource(getGPDMList());//new thread 1
multiSortList.setDefaultOrAddValue(valueList);//new thread 2
}
});
when the text changing too fast ,and the thread 1 or thread 2 does't excute completely,and the maybe some problem,so i want add the synchronized like this
public synchronized void modifyText(ModifyEvent e),
is this still a override method and will it work?
"Whether or not a method is synchronized is an implementation detail of the method. Synchronization isn't specified anywhere as a declarative contract - it's not like you can synchronize in interfaces, either.
How a class implements whatever thread safety guarantees it provides is up to it."
Taken from here
Adding the synchronized keyword does not get in the way of overriding a method (it is still overridden) because the method's signature remains the same.
For more details see JLS-ยง9.4.1.3
You can override a synchronized method and you can also remove synchronized keyword.
abstract class SynchronizedClass {
public synchronized String myIterfaceMethod(String str){
return str;
}
}
public class OverrideSynchronozied extends SynchronizedClass{
#Override
public String myIterfaceMethod(String str){
return str;
}
public static void main(String[] args) {
SynchronizedClass ss = new OverrideSynchronozied();
System.out.println(ss.myIterfaceMethod("Class Instance"));
}
}
Lets say I have these two classes, one extending the other
public class Bar{
public void foo(){
}
}
public class FooBar extends Bar {
#Override
public void foo(){
super.foo(); //<-- Line in question
}
}
What I want to do is warn the user to call the super-class's method foo if they haven't in the override method, is this possible?
Or is there a way to know, using reflection that a method that overrides a method of its super-class calls the original method if I pass on the class type to the super?
for example:
public abstract class Bar{
public Bar(Class<? extends Bar> cls){
Object instance = getInstance();
if (!instance.getClass().equals(cls)) {
throw new EntityException("The instance given does not match the class given.");
}
//Find the method here if it has been overriden then throw an exception
//If the super method isn't being called in that method
}
public abstract Object getInstance();
public void foo(){
}
}
public class FooBar extends Bar {
public FooBar(){
super(FooBar.class);
}
#Override
public Object getInstance(){
return this;
}
#Override
public void foo(){
super.foo();
}
}
Maybe even an annotation I can put on the super method so it shows that it needs to be called?
EDIT
Note, its not the super class that needs to call the foo method, it would be someone calling the sub class's foo method, for example a database close method
I would even be happy with making the method "un-overrideable" if it came down to it, but would still like to give it a custom message.
Edit 2
This here is what I wanted in a way:
But it would still be nice to have the above, or even give them a custom message to do something else like, Cannot override the final method from Bar, please call it from your implementation of the method instead
EDIT: To answer the edited, question, which includes:
I would even be happy with making the method "un-overrideable"
... just make the method final. That will prevent subclasses from overriding it. From section 8.4.3.3 of the JLS:
A method can be declared final to prevent subclasses from overriding or hiding it.
It is a compile-time error to attempt to override or hide a final method.
To answer the original question, consider using the template method pattern instead:
public abstract class Bar {
public foo() {
// Do unconditional things...
...
// Now subclass-specific things
fooImpl();
}
protected void fooImpl();
}
public class FooBar extends Bar {
#Override protected void fooImpl() {
// ...
}
}
That doesn't force subclasses of FooBar to override fooImpl and call super.fooImpl() of course - but FooBar could do this by applying the same pattern again - making its own fooImpl implementation final, and introducing a new protected abstract method.
what you could do is something like following
public class Bar{
public final void foo(){
//do mandatory stuff
customizeFoo();
}
public void customizeFoo(){
}
}
public class FooBar extends Bar {
#Override
public void customizeFoo(){
//do custom suff
}
}
foo method made 'final' in superclass so that subclasses can't override and avoid doing mandatory stuff
I have a method with a synchronization statement on an "non-this" object
class Some_Class {
public A s = new A();
public void method_A() {
synchronized(s) {
....
}
}
}
Can I instead extend class A and synchronize as follows:
class B extends A {
public A a;
public B(A a) {
this.a = a;
}
public synchronized void some_m() {
...
}
}
class Some_Class {
public A s = new A();
public void method_A() {
B b = new B(s);
b.some_m();
}
}
Are these two synchronizations equivalent?
No, they're not equivalent. This method here:
public synchronized void some_m() {
...
}
Does the same as this one:
public void some_m() {
synchronized(this) {
...
}
}
Or in other words
Your first code option synchronises on an instance of A in Some_Class (a class member, visible to everyone).
Your second code option synchronises on the instance of B within Some_Class.method_A() (a local variable, invisible to the outside of that method)
No, they are not equivalent. In second case you actually don't have synchronization at all. Because some_m method synchronized on instance of B. So you create local instance of B and call method on it. This method is synchronized only on this local instance of B and other threads don't care about it and can do whatever they want with s because it's not synchronized.
Can you describe what you want to achieve?
Synchronized block synchronizes the whole object while synchronized method synchronizes just that method. In the second case, some thread can still access other non-synchronized methods of the object.