扩展类中ClassName.this的代码重构技术咨询
ClassName.this References Great question—dealing with duplicate code that depends on outer class references like Foo.this or Bar.this can feel like a puzzle at first, but we can clean this up while preserving all original behavior. Here are two practical approaches:
1. Extract an Abstract Parent Class with Delegated Outer Reference
The core idea is to move all repeated logic into an abstract base class, and have your concrete classes (Foo, Bar) provide their own outer class reference via a simple method. This avoids hardcoding ClassName.this in the shared logic.
First, create the abstract base class to encapsulate duplicate behavior:
public abstract class BaseComponent { // Abstract method for concrete classes to return their own instance protected abstract BaseComponent getOuterInstance(); // Shared logic that uses the outer reference protected void doSomething() { someOtherAction(getOuterInstance()); } // Abstract inner class for shared child class behavior protected abstract class BaseChildComponent { protected void anotherAction() { createDialogBox(getOuterInstance()); } } // If these methods are shared across Foo/Bar, define them here; if not, make them abstract protected abstract void someOtherAction(BaseComponent outer); protected abstract void createDialogBox(BaseComponent outer); }
Then simplify your Foo class by extending the base class:
public class Foo extends BaseComponent { @Override protected BaseComponent getOuterInstance() { return Foo.this; // Explicitly return this instance } @Override protected void someOtherAction(BaseComponent outer) { // Foo-specific implementation here } @Override protected void createDialogBox(BaseComponent outer) { // Foo-specific dialog logic here } protected class FooChildClass extends BaseChildComponent { // Add Foo-specific child logic here, or leave empty to inherit parent behavior } }
Repeat the same pattern for Bar:
public class Bar extends BaseComponent { @Override protected BaseComponent getOuterInstance() { return Bar.this; } @Override protected void someOtherAction(BaseComponent outer) { // Bar-specific implementation here } @Override protected void createDialogBox(BaseComponent outer) { // Bar-specific dialog logic here } protected class BarChildClass extends BaseChildComponent { // Bar-specific child logic here } }
Why this works:
- We eliminate duplicate
doSomething()andanotherAction()logic entirely. - The
getOuterInstance()method lets each concrete class control what "outer reference" gets passed, preserving the original intent ofClassName.this. - You can still add class-specific logic in
Foo/Barand their inner classes without breaking the shared structure.
2. Use Generics for Type Safety (Optional)
If someOtherAction or createDialogBox expect a specific type (not just BaseComponent), you can add generics to the base class to avoid type casting later:
public abstract class BaseComponent<T extends BaseComponent<T>> { protected abstract T getOuterInstance(); protected void doSomething() { someOtherAction(getOuterInstance()); } protected abstract class BaseChildComponent { protected void anotherAction() { createDialogBox(getOuterInstance()); } } protected abstract void someOtherAction(T outer); protected abstract void createDialogBox(T outer); }
Then update Foo to use the generic type:
public class Foo extends BaseComponent<Foo> { @Override protected Foo getOuterInstance() { return Foo.this; } @Override protected void someOtherAction(Foo outer) { // No casting needed—we get a Foo instance directly } // ... rest of the class remains the same }
This makes the code more type-safe and avoids potential runtime errors from incorrect casting.
Key Notes:
- If your inner classes have unique logic beyond
anotherAction(), just override that method in the concrete child class (e.g.,FooChildClass). - Keep the base class focused only on shared behavior—don't force class-specific logic into it.
内容的提问来源于stack exchange,提问作者Jeffrey Kern

