我的目标是让一个包含所有执行数据库操作的函数的类干净利落地完成 - 也可以用一行代码调用,例如; DbFunctions.AddContact("fName", "lName");
我有一个DBAdapter类,我在教程中读过:
public class DBAdapter {
static final String KEY_ROWID = "_id";
static final String KEY_NAME = "name";
static final String KEY_EMAIL = "email";
static final String TAG = "DBAdapter";
static final String DATABASE_NAME = "MyDB";
static final String DATABASE_TABLE = "contacts";
static final int DATABASE_VERSION = 1;
static final String DATABASE_CREATE =
"create table contacts (_id integer primary key autoincrement, "
+ "name text not null, email text not null);";
final Context context;
DatabaseHelper DBHelper;
SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
try
{
db.execSQL(DATABASE_CREATE);
}
catch (SQLException ex)
{
ex.printStackTrace();
}
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
// some other database functions here... inserts, updates etc
}
我创建了自己的类来处理对DBAdapter的所有调用:
public static class DatabasesActivity extends Activity
{
static DBAdapter db;
// Called when activity is first created
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public static long addContact(String name, String email)
{
if (db == null) {
db = new DBAdapter(this); // <--- compiler error here
}
db.open();
long id = db.insertContact("Joe Bloggs", "joe@bloggs.com");
db.close();
return id;
}
}
在addContact
方法的第db = new DBAdapter(this);
行,我收到以下错误:Cannot use 'this' in a static context
。
我熟悉OOP概念,所以我理解为什么我收到了这个错误 - 但对于java本身来说是新手,我正在寻找替代方法来解决我想要实现的问题。 DBAdapter类构造函数接受context
参数,但我不确定为什么我自己没有编写该类。
澄清:
我理解错误发生的原因。 DBAdapter类构造函数接受context
参数,当我静态使用它时,我不知道传入什么作为context参数。我希望这个类是静态的,因为我不想每次想要使用它时都要实例化它。
我想我的真正问题是“为什么SQLiteOpenHelper需要上下文?”
答案 0 :(得分:7)
您在此处定义了static
方法:
public static long addContact(String name, String email)
静态方法和类变量与Class绑定,而不与Class的任何特定实例绑定。您不能在其中使用this
关键字,因为它引用了当前实例。其中一个选择是将方法声明为实例方法,从方法声明中删除static
关键字,如果方法逻辑确实取决于当前实例的状态。
我认为在this
方法中使用static
的问题是,在运行时如果您的代码将静态方法调用为 ClassName.staticMethodName(),则运行时我不知道如何在这种情况下解决this
。
答案 1 :(得分:2)
this
指的是该类的当前实例。
静态方法和对象存在于任何实例之外,这就是为什么不允许您在其中使用实例特定数据(如当前实例)
答案 2 :(得分:1)
您无法访问静态方法中的字段或方法。
Static methods do not point to any instance of the enclosing class.
所以this
关键字指的是该类的实例。
In a static context:
you won't have instance reference to current instance.
发生错误。
答案 3 :(得分:1)
您正在以不正确的静态功能访问此
通过删除静态修饰符使该函数非静态,然后它将正常工作
答案 4 :(得分:0)
您不能在静态上下文中使用“this”,因为它意味着您拥有该对象的实例,并且静态地您无法调用实例。
为什么需要静态类?
答案 5 :(得分:0)
通过查看此方法
// Called when activity is first created
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
我认为你根本不应该使用静态类,静态字段和静态方法。
只需创建一个Activity实例并使用它。如果您的所有程序都需要一个Activity对象 - 那么请使用Singleton Pattern。提供了Lazy和Eager实例化示例。
例如,急切的初始化将是:
public class DatabaseActivity extends Activity {
private static final DatabaseActivity INSTANCE= new DatabaseActivity();
private DatabaseActivity () {}
public static DatabaseActivity getInstance() {
return INSTANCE;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // calls nonstatic method onCreate from Activity class
setContentView(R.layout.activity_main);
}
}
答案 6 :(得分:0)
您已将您的课程视为静态。
只有嵌套类可以是静态的。通过这样做,您可以使用嵌套类,而无需外部类的实例。
class OuterClass{
public static class StaticNestedClass{
}
public class InnerClass{
}
public InnerClass getAnInnerClass(){
return new InnerClass();
}
//This method doesn't work
public static InnerClass getAnInnerClassStatically(){
return new InnerClass();
}
}
class OtherClass{
//Use of a static nested class:
private OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass();
//Doesn't work
private OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
//Use of an inner class:
private OuterClass outerclass= new OuterClass();
private OuterClass.InnerClass innerClass2 = outerclass.getAnInnerClass();
private OuterClass.InnerClass innerClass3 = outerclass.new InnerClass();
}
答案 7 :(得分:-2)
这是指向对象的指针..在静态上下文中,您没有对象。
为什么DatabaseActivy是一个静态类?因此,创建一个普通的类并创建它的对象