[英]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.