1

我的目标是拥有一个包含所有函数的类,这些函数可以干净利落地执行数据库操作——也可以用一行代码调用,例如;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参数,当我静态使用它时,我不知道该传递什么作为上下文参数。我希望这个类是静态的,因为我不想每次我想使用它时都实例化它。

我想我真正的问题是“为什么 SQLiteOpenHelper 需要上下文?”

4

8 回答 8

7

您在这里定义了一个static方法:

  public static long addContact(String name, String email)

静态方法和类变量与类相关联,而不是与类的任何特定实例相关联。您不能this在其中使用关键字,因为它指的是当前实例。static如果方法逻辑确实取决于当前实例的状态,则其中一种选择是将方法声明为实例方法,从方法声明中删除关键字。

我相信在方法this内部使用的问题static是,如果您的代码在运行时将静态方法调用为ClassName.staticMethodName(),则运行时将不知道如何this在这种情况下解决。

于 2013-06-21T10:51:24.890 回答
2

this指该类的当前实例。

静态方法和对象存在于任何实例之外,这就是为什么不允许在其中使用实例特定数据(如当前实例)的原因

于 2013-06-21T10:51:24.030 回答
1

您不能访问静态方法中的字段或方法。

 Static methods do not point to any instance of the enclosing class.

所以this关键字 this 指的是类的实例。

In a static context:
you won't have instance reference to current instance.

所以发生错误。

于 2013-06-21T10:51:16.757 回答
1

您正在一个不正确的静态函数中访问它

通过删除静态修饰符使函数非静态,然后它会正常工作

于 2013-06-21T10:52:00.663 回答
0

你不能在静态上下文中使用“this”,因为它意味着你有一个对象的实例,并且静态地你不能调用实例。

为什么需要静态类?

于 2013-06-21T10:52:10.983 回答
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);
} 
}
于 2013-06-21T10:54:35.143 回答
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();
}
于 2013-06-21T10:58:50.763 回答
-2

这是一个指向对象的指针。在静态上下文中,您没有对象。

为什么 DatabaseActivy 是一个静态类?所以创建一个普通类并创建它的一个对象

于 2013-06-21T10:52:02.640 回答