Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSF托管bean中列表的初始化_Jsf_Jsf 2_Arraylist_Java Ee 6 - Fatal编程技术网

JSF托管bean中列表的初始化

JSF托管bean中列表的初始化,jsf,jsf-2,arraylist,java-ee-6,Jsf,Jsf 2,Arraylist,Java Ee 6,我有一个关于POJO中列表初始化的问题,因为下面的代码如下: public class Person { //other fields... private List<String> friends=new ArrayList<>(); public List<String> getFriends() { return friends; } public void setFriends(List<St

我有一个关于POJO中列表初始化的问题,因为下面的代码如下:

public class Person {

 //other fields...
 private List<String> friends=new ArrayList<>();

     public List<String> getFriends() {
        return friends;
     }
     public void setFriends(List<String> friends) {
        this.friends = friends;
    }

}
公共类人物{
//其他领域。。。
private List friends=new ArrayList();
公共列表getFriends(){
回报朋友;
}
公众朋友(列出朋友){
这个。朋友=朋友;
}
}
还是像这样在其他类中进行初始化更好(比如Bean(JSF))

公共类人物{
//其他领域。。。
私人名单朋友;
公共列表getFriends(){
回报朋友;
}
公众朋友(列出朋友){
这个。朋友=朋友;
}
}

所以我的问题是什么方法更好?

在我看来,最好在构造函数中处理这个问题。如果使用默认构造函数,则初始化构造函数中的列表

public Person() {
    friends = new ArrayList<>();
}
公众人物(){
friends=newarraylist();
}
如果使用了接受参数的构造函数,则让调用类传入一个列表

public Person(ArrayList<> friends) {
    this.friends = friends;//friends
}
公众人物(ArrayList好友){
this.friends=friends;//friends
}

视情况而定。通常首选第一种方式,因为您可能希望稍后向集合中添加一些内容。如果您不知道您的收藏是否已初始化,您必须每次都检查它。

我建议:

public class Person {
     //other fields...
     private List<String> friends=new ArrayList<>();

     // returns a copy to protect original list
     public List<String> getFriends() {
        Collections.unmodifiableList(new ArrayList<>(friends));
     }
     public void addFriend(String> friend) {
        this.friends.add(friend);
     }
     public void addFriends(List<String> friends) {
        this.friends.addAll(friends);
     }
}
公共类人物{
//其他领域。。。
private List friends=new ArrayList();
//返回一个副本以保护原始列表
公共列表getFriends(){
集合。不可修改列表(新ArrayList(friends));
}
public void addFriend(字符串>好友){
this.friends.add(friends);
}
公共void addFriends(列出好友){
this.friends.addAll(friends);
}
}

我的建议是,在getter中添加一个空检查:

public class Person {
  //other fields...
  private List<String> friends;

  public List<String> getFriends() {
     if (this.friends == null) friends = new ArrayList<String>();
     return friends;
  }
}
或者,如果您要添加完整的列表:

personInstance.getFriends().addAll(someStringCollection);

如果它是您所说的托管bean,那么您应该使用
@PostConstruct

public class Person {
    private List<String> friends;
    @PostConstruct
    public void init(){
         friends = new ArrayList<String>();
    }

    //getter and setter...
}
公共类人物{
私人名单朋友;
@施工后
公共void init(){
friends=newarraylist();
}
//盖特和塞特。。。
}
  • 在JSF上下文中,通常不赞成在getter和setter中进行任何初始化。看

  • 此外,该契约还指定了安全特性,并保证如果在这样注释的方法中抛出异常,则不应将bean投入服务。在普通构造函数上没有这样的保证

  • public Person() {
        friends = new ArrayList<>();
    }
    
  • 在托管bean中,注入在构建之后立即发生。这意味着您在构造函数中执行的任何操作都不能依赖于任何注入的资源(通过
    @ManagedProperty
    )。而在
    @PostConstruct
    方法中,您可以访问托管bean上声明的所有资源

  • 编辑:需要注意的是,对于任何
    @ManagedBean
    ,只能有一个
    @PostConstruct
    ,因此所有重要的初始化都应该在其中进行

    还值得注意的是,虽然
    @PostConstruct
    方法是初始化支持bean变量/
    列表
    的理想位置,但是对于托管bean的范围有一些含义

  • @RequestScoped
    :在带有此注释的托管bean中,每次提交相关JSF视图时都将调用该方法。
    @RequestScoped
    bean在每次请求时都会被销毁并重新创建,这意味着根据您的设置,
    @PostConstruct
    中初始化的列表可能会在每次请求期间重置为空值或默认值。在某些情况下,重新初始化list mid JSF请求可能会导致转换错误

  • @ViewScoped
    :在带有此注释的托管bean中,只有当且仅当处理
    @ViewScoped
    bean的同一实例时,才能保证
    @PostConstruct
    方法运行一次。如果ViewScope bean被销毁并重新创建,则
    @PostConstruct
    方法将再次运行

  • @SessionScoped
    :带有此注释的bean创建一次并保持活动状态,直到用户的HTTP会话结束。在这个场景中,
    @PostConstruct
    方法保证只运行一次,直到bean被销毁为止

  • 另见


    如果他们先叫getter,你就完蛋了。这是一个
    managedBean
    ?@Eng.Fouad是的,这是managedBean。@kolossus我们以前不知道这是一个managedBean。鉴于新的信息,我同意,所以删除了我的评论。实际上,你不需要一直依赖于
    @PostConstruct
    。只有当且仅当您需要等待某些依赖项注入完成以便可以使用某些服务初始化列表时,才需要该注释。如果没有,你在你的问题中所做的是非常好的:)。然而,我确实有一种不好的感觉,您当前的体系结构不是最佳实践。数据库中是否有名为
    Person
    的实体?您可能希望
    清除
    或在
    集合中进行防御复制
    ,否则它实际上不是一个setter,而是一个
    addAll
    @bmorris591:谢谢,我更改了方法名称以避免混淆。与我自己的回答非常类似,但是,总体设计上,使用像这样的add和addAll方法可能更好。我怀疑我们在同一时间打字+1扩大OP希望行为的范围。这是一个称为“惰性初始化”的好策略。如果这是一个托管bean,您还需要一个无参数构造函数。在托管bean中,最好不要在构造函数中处理这个问题,我的示例更适合POJO而不是托管bean。虽然我不认为在默认的无参数构造函数中用m初始化有什么害处
    public class Person {
        private List<String> friends;
        @PostConstruct
        public void init(){
             friends = new ArrayList<String>();
        }
    
        //getter and setter...
    }