[英]Elements of ArrayList in Enum field Null. What is the correct way to do this?
我的理論是,在初始化時首先強制第一個枚舉初始化第二個枚舉以構建第一個ArrayList,但是當它構建第二個枚舉的ArrayList而不是陷入邏輯循環時,它將值設置為Null 。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (Ingredients ingredient: Ingredients.values()){
Log.d("debug", ingredient.recipes.toString());
}
for (Recipes recipe: Recipes.values()){
Log.d("debug",recipe.ingredients.toString());
}
}
enum Ingredients {
APPLE(new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER))),
BANANA(new ArrayList<>(Arrays.asList(Recipes.BANANA_FRITTER))),
FLOUR(new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER))),
SUGAR(new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER)));
final ArrayList<Recipes> recipes;
Ingredients(ArrayList<Recipes> products) {
this.recipes = products;
}
}
enum Recipes {
APPLE_FRITTER(new ArrayList<>(Arrays.asList(Ingredients.APPLE, Ingredients.FLOUR, Ingredients.SUGAR))),
BANANA_FRITTER(new ArrayList<>(Arrays.asList(Ingredients.BANANA, Ingredients.FLOUR, Ingredients.SUGAR)));
final ArrayList<Ingredients> ingredients;
Recipes(ArrayList<Ingredients> ingredients) {
this.ingredients = ingredients;
}
}
}
這是logcat:
D/debug: [APPLE_FRITTER]
D/debug: [BANANA_FRITTER]
D/debug: [APPLE_FRITTER, BANANA_FRITTER]
D/debug: [APPLE_FRITTER, BANANA_FRITTER]
D/debug: [null, null, null]
D/debug: [null, null, null]
不幸的是,這段代碼只是一個較大項目的一個小示例,該項目取決於此工作,如果我需要有效地廢棄所有內容並重新開始,則只需要進行一些確認即可。
當然,這里缺少一些技巧,那太棒了。 無論哪種方式,謝謝您的見解。
編輯:發布此消息后不久,我想回應認輸,我想出了一個我認為是可以解決該問題的出色重構。 它不起作用,但是產生了另一個錯誤。 分享給有興趣的人:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (Ingredients ingredient: Ingredients.values()){
Log.d("debug", ingredient.recipes.toString());
}
for (Recipes recipe: Recipes.values()){
Log.d("debug",recipe.ingredients.toString());
}
}
private final static ArrayList<Recipes> appleRecipes = new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER));
private final static ArrayList<Recipes> bananaRecipes = new ArrayList<>(Arrays.asList(Recipes.BANANA_FRITTER));
private final static ArrayList<Recipes> flourRecipes = new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER));
private final static ArrayList<Recipes> sugarRecipes = new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER));
private final static ArrayList<Ingredients> appleFritterIngredients = new ArrayList<>(Arrays.asList(Ingredients.APPLE, Ingredients.FLOUR, Ingredients.SUGAR));
private final static ArrayList<Ingredients> bananaFritterIngredients = new ArrayList<>(Arrays.asList(Ingredients.BANANA, Ingredients.FLOUR, Ingredients.SUGAR));
enum Ingredients {
APPLE(appleRecipes),
BANANA(bananaRecipes),
FLOUR(flourRecipes),
SUGAR(sugarRecipes);
final ArrayList<Recipes> recipes;
Ingredients(ArrayList<Recipes> products) {
this.recipes = products;
}
}
enum Recipes {
APPLE_FRITTER(appleFritterIngredients),
BANANA_FRITTER(bananaFritterIngredients);
final ArrayList<Ingredients> ingredients;
Recipes(ArrayList<Ingredients> ingredients) {
this.ingredients = ingredients;
}
}
}
和relevent logcat:
D/debug: [APPLE_FRITTER]
D/debug: [BANANA_FRITTER]
D/debug: [APPLE_FRITTER, BANANA_FRITTER]
D/debug: [APPLE_FRITTER, BANANA_FRITTER]
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.util.ArrayList.toString()' on a null object reference
問題是您有兩個枚舉在其構造函數中相互引用 ,這是一個循環引用。 您可以使用setter初始化來解決此問題。
免費提示: Arrays.asList返回新的ArrayList ,因此您無需再次將其包裝在新的ArrayList中 。 =)
enum Ingredients {
APPLE,
BANANA,
FLOUR,
SUGAR;
static{
APPLE.setRecipes(Arrays.asList(Recipes.APPLE_FRITTER));
BANANA.setRecipes(Arrays.asList(Recipes.BANANA_FRITTER));
FLOUR.setRecipes(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER));
SUGAR.setRecipes(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER));
}
List<Recipes> recipes;
private void setRecipes(List<Recipes> products){
this.recipes = products;
}
}
enum Recipes {
APPLE_FRITTER,
BANANA_FRITTER;
static{
APPLE_FRITTER.setIngredients(Arrays.asList(Ingredients.APPLE, Ingredients.FLOUR, Ingredients.SUGAR));
BANANA_FRITTER.setIngredients(Arrays.asList(Ingredients.BANANA, Ingredients.FLOUR, Ingredients.SUGAR));
}
List<Ingredients> ingredients;
private void setIngredients(List<Ingredients> ingredients) {
this.ingredients = ingredients;
}
}
Java Classloader是JRE的一部分,該JRE將Java類動態地加載到JVM中。 通常,僅按需加載類。
JVM何時開始類加載Ingredients 。 它在Ingredients.APPLE的構造函數中看到Recipes.APPLE_FRITTER ,因此開始類加載Recipes 。 它在Recipes.APPLE_FRITTER的構造函數中看到Ingredients.APPLE , Ingredients.FLOUR和Ingredients.SUGAR引用,但我們仍在Ingredients.APPLE的構造函數中,因此Ingredients.APPLE , Ingredients.FLOUR和Ingredients.SUGAR此處為null點,因此Recipes.APPLE_FRITTER的構造函數將所有項目獲取為null。
對不起,英語不好。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.