This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I have this Hash Set code and when I try to run my compile method on it I get the Null Pointer Exception: null error on it. Here is the code:
private void initKeywords() {
keywords = new HashSet<String>();
keywords.add("final");
keywords.add("int");
keywords.add("while");
keywords.add("if");
keywords.add("else");
keywords.add("print");
}
private boolean isIdent(String t) {
if (keywords.contains(t)) { ***//This is the line I get the Error***
return false;
}
else if (t != null && t.length() > 0 && Character.isLetter(t.charAt(0))) {
return true;
}
else {
return false;
}
}
The other lines that goes along with this error is:
public void compileProgram() {
System.out.println("compiling " + filename);
while (theToken != null) {
if (equals(theToken, "int") || equals(theToken, "final")) {
compileDeclaration(true);
} else {
compileFunction(); //This line is giving an error with the above error
}
}
cs.emit(Machine.HALT);
isCompiled = true;
}
private void compileFunction() {
String fname = theToken;
int entryPoint = cs.getPos();
if (equals(fname, "main")) {
cs.setEntry(entryPoint);
}
if (isIdent(theToken)) theToken = t.token(); ***//This line is giving an error***
else t.error("expecting identifier, got " + theToken);
symTable.allocProc(fname,entryPoint);
accept("(");
compileParamList();
accept(")");
compileCompound(true);
if (equals(fname, "main")) cs.emit(Machine.HALT);
else cs.emit(Machine.RET);
}
Are you sure you're running initKeywords() before isIdent()?
Either keywords or t is null. Using either a debugger or print statements it should be pretty simple to determine. If keywords is null, I'd assume that initKeywords() has not been called yet.
You probably want to call initKeywords from the constructor of this object.
I personally try to stay away from init methods. As previously mentioned, a constructor serves as an initializer, and so does the static block:
private final static Set<String> KEYWORDS = new HashSet<String>();
static {
keywords.add("final");
keywords.add("int");
keywords.add("while");
keywords.add("if");
keywords.add("else");
keywords.add("print");
}
Related
I'm currently investing a lot of time in cleaning up my code.
I have a lot of If statements that handles my signup form in frontend.
I have a feeling that after reading the book "Clean code". That this is just ugly, however I didn't seem to find any "amazing/incredible" cleanup format for my code below.
lets say I have 15 more if-statements then this will cause a lot of duplicates, so are there any major improvements possible?
User userByUsername = userRepo.findByUsername(user.getUsername());
User userByEmail = userRepo.findUserByEmail(user.getEmail());
if (userByUsername != null && userByEmail != null) {
throw new AccountException("Email and username already exist");
}
if (userByUsername != null) {
throw new AccountException("Username already exist");
}
if (userByEmail != null) {
throw new AccountException("Email already exist");
}
Another example with another method:
public void addConditions(ReservationDto reservationDto) {
long roomId = roomService.findRoomByRoomName(reservationDto.getRoomName()).getRoomId();
// Check for adding room: Roomcapacity for timeslote reached
// If maxCapacityAfternoon reached, then only add to afternoon possible
int roomCapacity = roomService.findRoomByRoomId(roomId).getCapacity();
boolean maxCapacityMorning = roomCapacity <= getNumberOfReservationsForRoomByDateVoormiddag(roomId, reservationDto.getDate());
boolean maxCapacityAfternoon = roomCapacity <= getNumberOfReservationsForRoomByDateNamiddag(roomId, reservationDto.getDate());
boolean isMorning = reservationDto.isMorning();
boolean isAfternoon = reservationDto.isAfternoon();
capacityConditions(reservationDto, maxCapacityMorning, maxCapacityAfternoon);
// Check: Reservation can only be made when it meets the following conditions
// - Same user
// - is active
// - Morning and date overlap
// - Afternoon and date overlap
Reservation mappedReservation = mapReservationDto(reservationDto);
int amountOfReservationsForDay = reservationRepo.existsReservationForDay(mappedReservation.getUsername(), mappedReservation.getDate());
if (isMorning && isAfternoon) {
if (amountOfReservationsForDay > 0) {
throw new ServiceException(RESERVATION_MSG + FOR_FULL_DAY + reservationDto.getDate());
}
if (reservationRepo.existsReservationForMorning(mappedReservation.getUsername(), mappedReservation.getDate()) > 0
|| reservationRepo.existsReservationForAfterNoon(mappedReservation.getUsername(), mappedReservation.getDate()) > 0
) {
throw new ServiceException(RESERVATION_MSG + "in de voor- of namiddag.");
}
}
if (isMorning && !isAfternoon) {
if (amountOfReservationsForDay > 0) {
throw new ServiceException(RESERVATION_MSG + FOR_FULL_DAY + reservationDto.getDate());
}
if (reservationRepo.existsReservationForMorning(mappedReservation.getUsername(), mappedReservation.getDate()) > 0) {
throw new ServiceException(RESERVATION_MSG + "in de voormiddag.");
}
}
if (!isMorning && isAfternoon) {
if (amountOfReservationsForDay > 0) {
throw new ServiceException(RESERVATION_MSG + FOR_FULL_DAY + reservationDto.getDate());
}
if (reservationRepo.existsReservationForAfterNoon(mappedReservation.getUsername(), mappedReservation.getDate()) > 0) {
throw new ServiceException(RESERVATION_MSG + "in de namiddag");
}
}
if (!isMorning && !isAfternoon) {
throw new ServiceException("Selecteer een tijdstip voor uw reservatie");
}
}
As you can see my project has a lot of conditions when I want to add a reservation. These are only the add conditions and don't take into account the room capacity check. Which is a long list of If's as well
You could create an enum for all the data validation exceptions that can be thrown
public enum DataValidationError {
USERNAME_EXISTS,
EMAIL_EXISTS,
...
}
public static class AccountException extends Exception {
private final List<DataValidationError> errors;
public AccountException(List<DataValidationError> errors) {
this.errors = errors;
}
public List<DataValidationError> getErrors() {
return errors;
}
}
Usage:
List<DataValidationError> errors = new ArrayList<>();
User userByUsername = userRepo.findByUsername(user.getUsername());
User userByEmail = userRepo.findUserByEmail(user.getEmail());
if (userByUsername != null) {
errors.add(DataValidationError.USERNAME_EXISTS);
}
if (userByEmail != null) {
errors.add(DataValidationError.EMAIL_EXISTS);
}
if (!errors.isEmpty()) {
throw new AccountException(errors);
}
This way you could add as many errors in the enum and keep adding them to a list and throw it only once at the end.
I am not sure if any really major improvement can be applied here. But for example since you are throwing the same type of exception you might play around your error message and throw exception only once. Like:
if(userByEmail != null || userByUsername != null){
String message = (userByEmail != null ? "Email" : "Username") + " already exist";
if(userByEmail != null && userByUsername != null){
message = "Email and username already exist";
}
throw new AccountException(message);
}
For make the code more extensible and close I would use a chain of validation for this kind of things. If you know about the SOLID principle, you have a problem of SRP and OCP. By implementing a chain of validation, you would have each node have one purpose and you could easily and more validation in the futur. After you just have to create a chain !
The thing is that validation is ONE thing, so I would too create lost of tiny function with good names, so the reader can "escape early" the reading if needed.
Here is the design patern that could help you: https://refactoring.guru/design-patterns/chain-of-responsibility
I think you repository should thow those exceptions too ! If you can't find a user throw an exception in your repository. You'll have less validation all over you code and it's easyer to read.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
So, I was trying to add a class to an ArrayList, but when I do it gives me a Null Pointer Exception. I'm sure I am just overlooking a variable that I thought was initialized, but I can't figure it out.
This is the class:
enum WebType { GoogleResult, Webpage };
public class Webpage {
WebType type;
String pageName;
String content;
String url;
String MLA = "";
public Webpage(String pageName, String content, String url, WebType type){
this.type = type;
this.pageName = pageName;
this.content = content;
this.url = url;
this.MLA = ""; // Temp
}
// TODO: Make Citation Maker
}
This is where I add the class to the ArrayList:
public void Start(){
for(Integer i = 0; i < tags.size(); i++){
if(tags.get(i) == null)
return;
Webpage page = Google(tags.get(i));
parseList.add(page); // The Error is on this line!
log.append("Added " + page.url + " to parse list");
}
for(Integer i = 0; i < parseList.size(); i++){
ParsePageCode(parseList.get(i));
}
}
Here is the Google function, it googles whatever you tell it to and returns the page information:
public Webpage Google(String search){
String url = "https://www.google.com/search?q=" + search;
String content = "";
try {
URLEncoder.encode(url, "UTF-8");
} catch (UnsupportedEncodingException e) {
log.append("\n Unsupported Encoding Contacting Google");
}
try {
content = GetPageCode(url);
} catch (IOException e) {
log.append("\n Unable To Reach Google");
log.append(e.getMessage());
}
Webpage w = new Webpage("Google Result For " + search, content, url, WebType.GoogleResult);
// System.out.println(search + url + WebType.GoogleResult);
return w;
}
Any Ideas?
On the line that is throwing the exception, parseList is the only variable being dereferenced. The only other variable on that line is page, and it doesn't matter if page is null because you can add null elements to a List. So, it must be parseList causing the NPE.
Actually there is no problem adding null to a collection of Objects. Retrieving the object and invoking its members later may cause NPE.
You have told is that the problem is on the line where you do add the object. The only way there to cause NPE is calling add() upon null. So that's your collection parseList that is not initialized yet. Maybe it's a field in the class and was never initialized to an actual object of type ArrayList, but it's only declared.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
We are trying to display information in a textarea from a database table.
public void displayEmployees()
{
String sqlDisplayQuery ="";
sqlDisplayQuery+= "Select * from JAVAUSER.Employee";
System.out.println(sqlDisplayQuery);
Driver.sendDBCommand(sqlDisplayQuery);
try
{
while (dbResults.next())
{
int employeeID= dbResults.getInt(1);
String employeeFName = dbResults.getString(2);
String employeeLName = dbResults.getString(3);
System.out.println("Employee " +employeeID + employeeFName + employeeLName);
txtaOutput.appendText("Employee" +employeeID + employeeFName + employeeLName);
}
}
catch (SQLException e)
{
System.out.println(e.toString());
}
}
public static boolean isNumeric(String string)
{
try
{
double num = Double.parseDouble(string);
}
catch(NumberFormatException e)
{
return false;
}
return true;
}
public static void sendDBCommand(String sqlQuery)
{
String URL = "jdbc:oracle:thin:#localhost:1521:XE";
String userID = "javauser";
String userPASS = "javapass";
OracleDataSource ds;
try
{
ds = new OracleDataSource();
ds.setURL(URL);
dbConn= ds.getConnection(userID, userPASS);
commStmt = dbConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
dbResults= commStmt.executeQuery(sqlQuery);
}
catch (SQLException e)
{
System.out.println(e.toString());
}
}
We are getting an null pointer exception at the while loop within the try statement. The SQL does not have any errors. Any help would be appreciated
Looks like the dbResults field is static on the Driver class - this could cause serious problems with multi-threading, and does not utilize proper object-orientation - but that's beyond the scope of the question i guess.
Looking at the loop:
int employeeID= dbResults.getInt(1);
This is fine-ish, even though getInt() won't throw an NPE, you might want to check if the value was SQL null with ResultSet.wasNull().
String employeeFName = dbResults.getString(2);
String employeeLName = dbResults.getString(3);
These can be null, but won't throw NPE either.
System.out.println("Employee " +employeeID + employeeFName + employeeLName);
txtaOutput.appendText("Employee" +employeeID + employeeFName + employeeLName);
Here, in both lines, you concat strings that could be null, so these two are potential sources of NullPointerExceptions. I am just wondering if you got line numbers in your stacktrace that could help identifying the exact location...?
If you want to check what can/cannot return null from an SQL ResultSet, check this.
I'm stuck on the very last part of my homework. I have to return an Agent value, but for some reason I keep getting an error saying that "This method must return type Agent", even though what I am returning is an Agent. Any help would be greatly appreciated.
import java.io.File;
import java.util.HashMap;
import jeff.ini.Ini;
public class ConfigLoader
{
private Ini _ini;
private HashMap<String, Space> _spaces = new HashMap<String, Space>();
private HashMap<String, Portal> _portals = new HashMap<String, Portal>();
private HashMap<String, Agent> _agents = new HashMap<String, Agent>();
public ConfigLoader(File iniFile)
{
_ini = new Ini(iniFile);
}
public Agent buildAll()
{
_buildSpaces();
_buildPortals();
_buildExits();
_buildDestinations();
_buildAgents();
return _selectStartAgent();
}
private void _buildSpaces(){
for(String spaceName : _ini.keys("spaces")){
String descrip= _ini.get("spaces", spaceName);
String image= _ini.get("images", "images");
Space space1= new Space(spaceName, descrip, image, null);
_spaces.put(spaceName, space1);
}
}
private void _buildPortals(){
for(String portalName : _ini.keys("portals")){
String descrip= _ini.get("portal", portalName);
Portal portal1=new Portal(portalName, descrip, null);
_portals.put(portalName, portal1);
}
}
private void _buildExits(){
for(String spaceName : _ini.keys("exits")){
String spaceExit = _ini.get("exits", spaceName);
Space space = _spaces.get(spaceName);
Portal exit = _portals.get(spaceExit);
space.setPortal(exit);
}
}
private void _buildDestinations(){
for(String portalName : _ini.keys("destinations")){
String destination = _ini.get("destinations", portalName);
Space des = _spaces.get(destination);
if(des == null){
System.out.print("ERROR");
System.exit(1);
}
else{
Portal portal = _portals.get(portalName);
portal.setDestination(des);
}
}
}
private void _buildAgents(){
for(String agentName : _ini.keys("agents")){
String agent = _ini.get("agents" , agentName);
Space space = _spaces.get(agent);
if(space == null){
System.out.print("ERROR");
System.exit(1);
}
else{
Agent a = new Agent(space, agentName);
_agents.put(agentName, a);
}
}
}
private Agent _selectStartAgent(){
for(String agentName : _ini.keys("start")){
String agent = _ini.get("start" , agentName);
Agent agent1 = _agents.get(agent);
if(agent == null){
System.out.print("ERROR");
System.exit(1);
}
else{
return agent1;
}
}
}
}
A method should return a value in all the different execution path. You are returning a value only in else block, which means in case when else block is not executed the value will not be returned and hence compiler complains for it. Make sure that you return a value in all different execution path, when if is not executed, when else is not executed, when for loop itself is not executed.
The key is that all execution paths must return a value of type Agent, which could be null. The calling method must, as usual, check whether the returned value is null.
Now let's look at what are missing:
The if branch does not return a value, instead it abruptly exits.
If the for loop is never entered, the method does not return anything either.
With all those fixed, the entire code could be something like:
for (String agentName : _ini.keys("start")){
String agent = _ini.get("start" , agentName);
Agent agent1 = _agents.get(agent);
if (agent == null){
System.out.print("ERROR");
return null;
} else {
return agent1;
}
return null;
}
The problem with your _selectStartAgent method is that a return isn't executed in all cases. You do call System.exit(1) inside this method, but the compiler doesn't care; it sees that as another method call. Even if it won't return because the JVM will be exited, the compiler still requires a return in the case where agent is null.
You could just place a return null; after System.exit(1). However, this method shouldn't be handling an error. It just needs to report the error. Just have it return null (or have it throw an exception).
if(agent == null){
return null;
// or
// throw an exception here
}
The method that calls _selectStartAgent should check for null (or handle the exception, depending on which you choose).
Additionally, the compiler doesn't assume that there will be an iteration of any for loop. There is no return there either. You can place a return statement after the for loop, to ensure that there is a return when there is no iteration of the for loop.
I believe it has to do with if your for loop doesn't have anything to loop through. In that case, you have no return statement.
Try adding return null after the for loop.
private Agent _selectStartAgent(){
for(String agentName : _ini.keys("start")){
String agent = _ini.get("start" , agentName);
Agent agent1 = _agents.get(agent);
if(agent == null){
System.out.print("ERROR");
System.exit(1);
}
else{
return agent1;
}
}
return null;
}
I 'm havin a problem with resolving enum.
I checked previous answers like why enum could not be resolved in JAVA?
and I did the answer but I still get the error. also followed another solution to change the compiler compliance level. but in my case it is originally set to 1.6
what should be changed here ?
Code :
CellTypes.java
public enum CellTypes {
STRING,LIST,PATH
}
in the event of canModify which is overriden
desc :
/**
* #see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object,
* java.lang.String)
*/
just calling setEditor method and setEditor is as follows
public void setEditor(int editorIndex, List<Object> choices, CellTypes UIType) {
try {
if (choices != null) {
String[] choicesArray = new String[choices.size()];
for (int i = 0; i < choices.size(); i++) {
choicesArray[i] = choices.get(i).toString();
}
editors[editorIndex] = new ComboBoxCellEditor(table, choicesArray, SWT.READ_ONLY);
editors[editorIndex].getControl().addTraverseListener(traverseListener);
columnEditorTypes[editorIndex] = EditorTypes.COMBO;
} else if(UIType == CellTypes.PATH) { // it gives "cannot resolve type " here
editors[editorIndex] = standardEditors.get(EditorTypes.PATH);
columnEditorTypes[editorIndex] = EditorTypes.PATH;
}
else
{
editors[editorIndex] = standardEditors.get(EditorTypes.STRING);
columnEditorTypes[editorIndex] = EditorTypes.STRING;
}}
catch(Exception e)
{
e.printStackTrace();
}
}
causes an error of cannot resolve CellTypes type
where ct is recognised as enum and its type is STRING
Change
if (ct = CellTypes.STRING)
to
if (ct == CellTypes.STRING)
You are assigning iso. comparing.
If I understood you correctly, you are comparing the String name of the enum value to an enum value. Try this:
if (CellTypes.valueOf(ct) == CellTypes.STRING)