使用硬编码值仍然得到java.lang.NullPointerException

时间:2017-09-27 07:19:10

标签: java nullpointerexception

(背景:我的新高级开发人员想知道我的java技能,他给了我一个导致错误的程序。他希望我解释错误发生的原因以及如何解决错误。

我运行程序,我发现错误是java.lang.NullPointerException,它还显示了堆栈跟踪。根据我的知识(manbe我错了),通常第一条消息表明错误发生在哪个类中,在我的例子中,它显示

java.lang.NullPointerException at action.userMaint.AdminUserMaintAction.save(AdminUserMaintAction.java:301)

我向新的高级开发人员询问源代码,因为我想查看AdminUserMaintAction类中的代码

在发布问题之前,我已阅读有关错误的帖子What is a NullPointerException, and how do I fix it?

我注意到有关于此错误的其他帖子,所以我大致知道空指针异常,因为对象或其他内容为空。

但是,我仍然无法弄清楚如何解决异常,所以我决定在这里发表我的问题。

内容

在AdminUserMaintAction类中,我找到了save()方法。这是代码。

public String save(){       
    String curloginId = (String) session.get("_loginid"); 
    funcid =1;

    AdmFunc admFunc = new AdmFunc();     
    admFunc.setCreatedBy(curloginId);
    admFunc.setCreatedDate(createdDate);
    admFunc.setFuncid(funcid);
    admFunc.setLoginid(curloginId);
    admFunc.setModifiedBy(curloginId);
    admFunc.setModifiedDate(modifiedDate);

    try {
        adminUserMaintService.insert(admFunc);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }                       
    return view2();     
}

从堆栈跟踪中,此行发生错误

adminUserMaintService.insert(admFunc);

我发现有一个名为AdminUserMaintService类的类,插入方法就在那里。这是代码

public void insert(AdmFunc admFunc) throws SQLException{

    Connection conn = jdbcTemplate.getDataSource().getConnection();

     String sql = "INSERT INTO ADM_FUNC (LOGINID, FUNC_ID, CREATED_DATE, CREATED_BY, MODIFIED_DATE, MODIFIED_BY)  VALUES (NULL,NULL,NULL,NULL,NULL,NULL)";

    PreparedStatement pstmt = conn.prepareStatement(sql);

    pstmt.setString(1, admFunc.getLoginid());
    pstmt.setInt(2, admFunc.getFuncid());
    pstmt.setTimestamp(3, admFunc.getCreatedDate());
    pstmt.setString(4, admFunc.getCreatedBy());
    pstmt.setTimestamp(5, admFunc.getModifiedDate());
    pstmt.setString(6, admFunc.getModifiedBy());

    pstmt.execute();
}

我读了代码,看起来很好,我不知道为什么会出现错误,因为没有代码表示返回空值。

另外,在AdminUserMaintService类中有一点我不明白,insert方法有硬编码值,如“loginid”,3,“created by”和“modified by”,仍然得到空指针异常?

我认为问题出在AdminUserMaintAction类中,因为stacktrace指示那里的错误

在AdminUserMaintAction类中,我使用System.out.println在代码中打印值。这是我在代码中添加的内容

public String save(){       
    String curloginId = (String) session.get("_loginid"); 

    funcid =1;

    AdmFunc admFunc = new AdmFunc();     
    admFunc.setCreatedBy(curloginId);
    admFunc.setCreatedDate(createdDate);
    admFunc.setFuncid(funcid);
    admFunc.setLoginid(curloginId);
    admFunc.setModifiedBy(curloginId);
    admFunc.setModifiedDate(modifiedDate);

    //I try to print values to see what values inside the code 
    System.out.println("admfunc.setFuncid is " + admFunc.getFuncid()); //it shows 1
    System.out.println("admfunc.setCreatedBy is " + admFunc.getCreatedBy() ); //it shows tester
    System.out.println("admfunc.setCreatedDate is " + new Timestamp(new Date().getTime()) ); //it shows today's date and time
    System.out.println("admfunc.setMofifiedBy is " + admFunc.getModifiedBy() ); //it shows tester
    System.out.println("admfunc.setModifiedDate is " +new Timestamp(new Date().getTime()) ); //it shows today's date and time
    System.out.println("admFunc value is" + admFunc);   //it shows jpa.AdmFunc@624c08e2
    System.out.println("start save ...");   
    System.out.println("");

    //adminUserMaintService.insert(admFunc); // I try this code and it occurs the same error
//  this.adminUserMaintService.insert(admFunc); // I try this code and it occurs the same error too

    try {
        adminUserMaintService.insert(admFunc);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println("end save ...");
    return view2();

}

另外,我将硬编码值放在AdminUserMaintService类的insert方法中。

public void insert(AdmFunc admFunc) throws SQLException{

    Connection conn = jdbcTemplate.getDataSource().getConnection();

     String sql = "INSERT INTO ADM_FUNC (LOGINID, FUNC_ID, CREATED_DATE, CREATED_BY, MODIFIED_DATE, MODIFIED_BY)  VALUES (NULL,NULL,NULL,NULL,NULL,NULL)";

    PreparedStatement pstmt = conn.prepareStatement(sql);

    pstmt.setString(1,"loginid"); 
    pstmt.setInt(2, 3);
    pstmt.setTimestamp(3,new Timestamp(new Date().getTime())); 
    pstmt.setString(4, "created by"); 
    pstmt.setTimestamp(5,new Timestamp(new Date().getTime()));  
    pstmt.setString(6, "modified by"); 

    pstmt.execute();

    try {
            conn.setAutoCommit(false);          

            pstmt.setString(1,"loginid"); 
            pstmt.setInt(2, 3);
            pstmt.setTimestamp(3,new Timestamp(new Date().getTime())); 
            pstmt.setString(4, "created by"); 
            pstmt.setTimestamp(5,new Timestamp(new Date().getTime()));  
            pstmt.setString(6, "modified by"); 

            pstmt.execute();
            conn.commit();

        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            conn.rollback();
        } finally {
            pstmt.close();
            conn.setAutoCommit(true);
        }


}

然而,当我运行程序时,它仍然给我空指针异常。

我使用System.out.println打印东西,我注意到该值不为null。我不明白为什么我得到异常,我在AdminUserMaintAction和AdminUserMaintService类中对该值进行了硬编码。

所以我想问一些问题,

  1. 硬编码值为空? (据我所知,我不认为硬编码值等于null,因为使用System.out.println可以打印该值。但是在我的情况下,它似乎不同,它仍然显示空指针异常,指示行动中的位置.userMaint.AdminUserMaintAction.save())

  2. 因为我注意到stacktrace指示异常发生在action.userMaint.AdminUserMaintAction.save()中,所以我去那个类,该方法尝试打印值,我可以看到值,所以这意味着我可以确认该对象不为空?

  3. 如果对象不为null,有什么方法可以找到解决空指针异常的问题吗?

  4. 感谢您的时间。

    编辑 谢谢大家的评论和答案,我注意到adminUserMaintService为null,我把一些代码放在一起,使它不是null。因此,当我运行代码时,虽然它仍然显示空指针异常,但它显示异常在

    Connection conn = jdbcTemplate.getDataSource().getConnection();
    

    这意味着此时adminUserMaintService不为空。

    所以现在我将研究为什么空指针改变位置。

    感谢。

3 个答案:

答案 0 :(得分:1)

如果您说AdminUserMainTAction类中的第301行实际上是

adminUserMaintService.insert(admFunc);

这意味着adminUserMaintServicenull。因此,在{&#34}之前将代码添加到AdminUserMainTService中并没有多大帮助,因为错误发生在"之前。尝试找出实例成员adminUserMaintService何时被实例化以及如何实例化。它永远不会被实例化,或者使用一些本身返回null而不是实例的工厂方法。

答案 1 :(得分:0)

让我们看一下你的异常堆栈跟踪片段:

- (void)viewDidLoad {
    //Top view
    self.topView = [TLProfileHeaderView newAutoLayoutView];
    self.topView.backgroundColor = [UIColor redColor]; 
    [self.view addSubview:self.topView];
    [self.topView autoPinEdgeToSuperviewEdge:ALEdgeTop];
    [self.topView autoPinEdgeToSuperviewEdge:ALEdgeLeft];
    [self.topView autoPinEdgeToSuperviewEdge:ALEdgeRight];
    [self.topView autoMatchDimension:ALDimensionHeight toDimension:ALDimensionWidth ofView:self.topView withMultiplier:0.53];

    UIButton *inviteFriendsButton = [UIButton newAutoLayoutView];
    [inviteFriendsButton setTitle:@"INVITE FRIENDS TO USE MY APP" forState:UIControlStateNormal];
    [inviteFriendsButton setBackgroundColor:[UIColor greenColor]];
    [inviteFriendsButton addTarget:self action:@selector(presentNextController:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:inviteFriendsButton];

    [inviteFriendsButton autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.topView];
    [inviteFriendsButton autoPinEdgeToSuperviewEdge:ALEdgeLeft];
    [inviteFriendsButton autoPinEdgeToSuperviewEdge:ALEdgeRight];
    [inviteFriendsButton autoSetDimension:ALDimensionHeight toSize:[TLDimensionHelper gpsCellHeight]*0.8];

    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchController.searchBar.placeholder = @"Enter name or email";
    self.searchController.searchResultsUpdater = self;
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.searchController.searchBar.delegate = self;
    self.searchController.searchBar.clipsToBounds = YES;
    self.definesPresentationContext = YES;
}


- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [self.navigationController setNavigationBarHidden:NO animated:YES];
    self.navigationController.navigationBar.translucent = NO;
    [self setEdgesForExtendedLayout:UIRectEdgeNone];
}

- (void)presentNextController:(UIButton *)sender {
    MyNextVC *nextVC = [MyNextVC new];
    [self presentViewController:nextVC animated:YES completion:nil];
}

这意味着:

  1. I Refused to split GroupingShuffleReader <at position ShufflePosition(base64:AAAABOA3nVgAAQ) of shuffle range [ShufflePosition(base64:AAAAAAD_AP8A_wD_AAE), ShufflePosition(base64:AAAABOA3nVkAAQ))> at ShufflePosition(base64:AAAABOA3nVkAAQ) E Refusing to split <at position ShufflePosition(base64:AAAABOA3nVgAAQ) of shuffle range [ShufflePosition(base64:AAAAAAD_AP8A_wD_AAE), ShufflePosition(base64:AAAABOA3nVkAAQ))> at ShufflePosition(base64:AAAABOA3nVkAAQ): proposed split position out of range I Proposing dynamic split of work unit our-project-id;2017-09-26_09_29_26-14666853265610614017;1268593085087986642 at {"fractionConsumed":1.0,"position":{"shufflePosition":"AAAABOA3nVkAAQ"}} I Setting node annotation to enable volume controller attach/detach 方法mRootRef.child("users").child(currentUser.getUid()).push().setValue(and so on...
  2. 中发生了异常
  3. 该异常是在班级java.lang.NullPointerException at action.userMaint.AdminUserMaintAction.save(AdminUserMaintAction.java:301)
  4. 的第301行引发的

    发生action.userMaint.AdminUserMaintAction然后您使用空指针调用变量上的某个类字段。 因此,理论上,您最好在IDE或其他编号行的文本处理器中打开类save()。它将帮助您找到确切的代码。 没有额外的信息很难建议更多。但我认为你硬编码了错误的代码。

答案 2 :(得分:0)

堆栈跟踪中可能包含多个异常。所以你检查最后'由'stmt指出npe的来源。