我想知道,在创建新的Activity
类然后重写onCreate()
方法时,在eclipse中我总是自动添加:super.onCreate()
。这是怎么发生的?抽象或父类中是否有一个强制执行此操作的java关键字?
我不知道调用超类是否违法,但我记得在某些方法中我因为没有这样做而抛出异常。这也是内置到java中的吗?你可以使用一些关键字来做到这一点吗?或者它是如何完成的?
答案 0 :(得分:165)
这是在支持注释库中添加的:
dependencies {
compile 'com.android.support:support-annotations:22.2.0'
}
http://tools.android.com/tech-docs/support-annotations
@CallSuper
答案 1 :(得分:77)
如果你想强制子类来执行父类的逻辑,一个常见的模式如下:
public abstract class SuperClass implements SomeInterface
{
// This is the implementation of the interface method
// Note it's final so it can't be overridden
public final Object onCreate()
{
// Hence any logic right here always gets run
// INSERT LOGIC
return doOnCreate();
// If you wanted you could instead create a reference to the
// object returned from the subclass, and then do some
// post-processing logic here
}
protected abstract Object doOnCreate();
}
public class Concrete extends SuperClass
{
@Override
protected Object doOnCreate()
{
// Here's where the concrete class gets to actually do
// its onCreate() logic, but it can't stop the parent
// class' bit from running first
return "Hi";
}
}
这实际上并没有回答你关于是什么促使Eclipse自动将超类调用插入到实现中的问题;但是我不认为这是可行的方法,因为这总是可以删除。
您实际上不能强制执行方法必须使用Java关键字或类似的东西调用超类的版本。我怀疑你的异常只是来自父类中的一些代码,它们检查你的方法无效的预期不变量或其他东西。请注意,这与抛出异常略有不同,因为您未能调用super.onCreate()
。
答案 2 :(得分:9)
以下是Activity#onCreate()
的来源 - 几乎所有评论(original - see line ~800):
/**
* Called when the activity is starting. This is where most initialization
* should go: calling {@link #setContentView(int)} to inflate the
* activity's UI, using {@link #findViewById} to programmatically interact
* with widgets in the UI, calling
* {@link #managedQuery(android.net.Uri , String[], String, String[], String)} to retrieve
* cursors for data being displayed, etc.
*
* <p>You can call {@link #finish} from within this function, in
* which case onDestroy() will be immediately called without any of the rest
* of the activity lifecycle ({@link #onStart}, {@link #onResume},
* {@link #onPause}, etc) executing.
*
* <p><em>Derived classes must call through to the super class's
* implementation of this method. If they do not, an exception will be
* thrown.</em></p>
*
* @param savedInstanceState If the activity is being re-initialized after
* previously being shut down then this Bundle contains the data it most
* recently supplied in {@link #onSaveInstanceState}. <b><i>Note: Otherwise it is null.</i></b>
*
* @see #onStart
* @see #onSaveInstanceState
* @see #onRestoreInstanceState
* @see #onPostCreate
*/
protected void onCreate(Bundle savedInstanceState) {
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mCalled = true;
}
所以,我的猜测是ADT Eclipse插件会自动为你调用super.onCreate()
。但总的来说,这是一个猜测。
答案 3 :(得分:8)
如果你想确保同样调用superclass-method,你必须欺骗一下:不要让superclass-method被覆盖,而是让它调用一个可覆盖的受保护方法。
class Super
{
public final void foo() {
foo_stuff();
impl_stuff();
}
protected void impl_stuff() {
some_stuff_that_you_can_override();
}
}
class Base extends Super
{
protected void impl_stuff() {
my_own_idea_of_impl();
}
}
这样,用户必须调用Super.foo()或Base.foo(),它将始终是基类版本,因为它被声明为final。特定于实现的东西在impl_stuff()中,可以覆盖。
答案 4 :(得分:8)
要回答您的实际问题,自动创建对super.onCreate()的调用是ADT插件的一项功能。 在java中,你不能直接强制子类调用方法的超级实现,afaik(参见其他答案中描述的模式来解决)。但是,请记住,在Android中,你是不是实例化活动对象(或服务对象)直接 - 你传递的意图,系统和系统实例化对象,并吁请它的onCreate()(与其他生命周期方法一起)。因此系统具有对Activity实例的直接对象引用,并且能够检查(可能)在onCreate()的超类实现中设置为true的一些布尔值。 虽然我不确切知道它是如何实现的,但它可能看起来像这样:
class Activity
{
onCreate()
{
superCalled = true;
...
}
...
}
在接收Intent并从中实例化Activity对象的“system”级别类中:
...
SomeActivitySubclass someActivitySubclassObject = new SomeActivitySubclass();
someActivitySubclassObject.onCreate();
if (!someActivityObject.isSuperCalled())
{
Exception e = new Exception(...) //create an exception with appropriate details
throw e;
}
我的猜测是它可能稍微复杂一点,但你明白了。 Eclipse会自动创建调用,因为ADT插件会告诉它,为方便起见。快乐的编码!
答案 5 :(得分:4)
Java中没有任何东西可以强制调用super,并且有很多例子你不想这样做。唯一可以强制调用super的地方是构造函数。所有构造函数都必须调用超类构造函数。如果你没有显式地写一个,那么将插入一个(无参数构造函数),如果没有无参数构造函数,那么你必须明确地调用它。
答案 6 :(得分:3)
Eclipse只是有用,提醒您可以根据需要调用超类实现。
你可能会收到一个错误,因为你没有做超级类所必需的事情,因为你没有调用它的实现。
答案 7 :(得分:1)
Eclipse只是帮助您正确行事并避免异常。
来自http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle)
派生类必须调用超类的此方法的实现。如果他们不这样做,将抛出异常。