Elettracompany.com

Компьютерный справочник
3 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Java exception in constructor

Java exception in constructor

Constructors

When writing code with exceptions, it’s particularly important that you always ask “If an exception occurs, will this be properly cleaned up?” Most of the time you’re fairly safe, but in constructors there’s a problem. The constructor puts the object into a safe starting state, but it might perform some operation—such as opening a file—that doesn’t get cleaned up until the user is finished with the object and calls a special cleanup method. If you throw an exception from inside a constructor, these cleanup behaviors might not occur properly. This means that you must be especially diligent while you write your constructor.

Since you’ve just learned about finally, you might think that it is the correct solution. But it’s not quite that simple, because finally performs the cleanup code every time, even in the situations in which you don’t want the cleanup code executed until the cleanup method runs. Thus, if you do perform cleanup in finally, you must set some kind of flag when the constructor finishes normally so that you don’t do anything in the finally block if the flag is set. Because this isn’t particularly elegant (you are coupling your code from one place to another), it’s best if you try to avoid performing this kind of cleanup in finally unless you are forced to.

In the following example, a class called InputFile is created that opens a file and allows you to read it one line (converted into a String) at a time. It uses the classes FileReader and BufferedReader from the Java standard I/O library that will be discussed in Chapter 12, but which are simple enough that you probably won’t have any trouble understanding their basic use:

The constructor for InputFile takes a String argument, which is the name of the file you want to open. Inside a try block, it creates a FileReader using the file name. A FileReader isn’t particularly useful until you turn around and use it to create a BufferedReader that you can actually talk to—notice that one of the benefits of InputFile is that it combines these two actions.

If the FileReader constructor is unsuccessful, it throws a FileNotFoundException, which must be caught separately. This is the one case in which you don’t want to close the file, because it wasn’t successfully opened. Any other catch clauses must close the file because it was opened by the time those catch clauses are entered. (Of course, this is trickier if more than one method can throw a FileNotFoundException. In that case, you might want to break things into several try blocks.) The close( ) method might throw an exception so it is tried and caught even though it’s within the block of another catch clause—it’s just another pair of curly braces to the Java compiler. After performing local operations, the exception is rethrown, which is appropriate because this constructor failed, and you wouldn’t want the calling method to assume that the object had been properly created and was valid.

In this example, which doesn’t use the aforementioned flagging technique, the finally clause is definitely not the place to close( ) the file, since that would close it every time the constructor completed. Because we want the file to be open for the useful lifetime of the InputFile object, this would not be appropriate.

The getLine( ) method returns a String containing the next line in the file. It calls readLine( ), which can throw an exception, but that exception is caught so getLine( ) doesn’t throw any exceptions. One of the design issues with exceptions is whether to handle an exception completely at this level, to handle it partially and pass the same exception (or a different one) on, or whether to simply pass it on. Passing it on, when appropriate, can certainly simplify coding. In this situation, the getLine( ) method converts the exception to a RuntimeException to indicate a programming error.

The dispose( ) method must be called by the user when finished using the InputFile object. This will release the system resources (such as file handles) that are used by the BufferedReader and/or FileReader objects. You don’t want to do this until you’re finished with the InputFile object, at the point you’re going to let it go. You might think of putting such functionality into a finalize( ) method, but as mentioned in Chapter 4, you can’t always be sure that finalize( ) will be called (even if you can be sure that it will be called, you don’t know when). This is one of the downsides to Java; All cleanup—other than memory cleanup—doesn’t happen automatically, so you must inform the client programmer that they are responsible, and possibly guarantee that cleanup occurs using finalize( ).

In Cleanup.java an InputFile is created to open the same source file that creates the program, the file is read in a line at a time, and line numbers are added. All exceptions are caught generically in main( ), although you could choose greater granularity.

One of the benefits of this example is to show you why exceptions are introduced at this point in the book—there are many libraries (like I/O, mentioned earlier) that you can’t use without dealing with exceptions. Exceptions are so integral to programming in Java, especially because the compiler enforces them, that you can accomplish only so much without knowing how to work with them.

Java Interview Questions For Beginners — 4 (Constructor, Exception handling, Generics, Multi threading)

Constructor

1. Can we make constructor private in Java ? if so what’s the use ?

Yes, we can make constructor private. But we can’t create Object for the class from outside the class since you can’t call private method from outside Class’s scope

Making constructor private is used in achieving singleton in Java.

2. Can you make constructor final?

No, Constructor can’t be final.

3. What is constructor overloading and what is the purpose of default constructor ?

Like method overloading, constructor can also be overloaded. For overloading, we have the same method name (here method name is same as class name since constructor) but difference in either of the following

  • Number of parameter
  • Type of parameter
  • Order of parameter

4. How many constructor a class can have ?

Constructor is a special method with class name as method name. Java supports constructor overloading. So we can have any number of constructors in Java.

But If you are not specifying any constructor, the compiler will add a default constructor to your class (constructor without parameters). So there will be at least one constructor in a Java Class.

Читать еще:  Console log javascript

5. Can constructor be inherited in subclass?

No, Constructor cannot be inherited in subclass. Because Constructor are not class members

Exception Handling

1. How to handle Checked Exception?

To handle Checked Exception, we can use any of the following two methods.

1. Use try/catch/finally & declare the Exception in catch block.

2. Use throws keyword next to method name & mention the Exception name.

If we fail to handle Checked Exception in any of the above method, compilation will fail

Generics

1. What is Generics in Java ?

Generics forces the Java programmer to store only specific type of objects. So whenever we are adding value at Collection its type will be checked at compile time itself. It mainly avoids ClassCastException. Generics uses <> (diamond operator) to specify type.

Sample 1:

In above example, we used non generic list (no type specified). So when we use get method in Line 5 we need explicit type casting to String.

Sample 2:

In above example, In line 2,3 we added String & in line 4, we added Integer.

When we use get method in Line 5, we try to cast as String, But We can’t convert Integer to String, so ClassCastException will occur for Integer type.

Sample 3:

Here we specified String in List declaration within <> bracket. Its called genetics. So list will only allow String. When we try to add integer 1 into list, the compiler will throw Exception

Multithreading

​​1. What are the ways of creating Thread in Java?

There are two ways of creating a Thread.

​​By extending Thread class

​​By implementing Runnable interface

​​2. What are the methods used to perform inter thread communication ?

Two or more threads can interact with each other using three methods such as

wait() (Release the lock & make the thread suspended)

notify() (Release the lock & Resumes a thread which is suspended)

notifyAll() (Release the lock & Resumes all thread which are suspended)

3. What is Synchronization in Java

The synchronized keyword prevents ​concurrent (same time)​​​ access to a block of code or object by multiple Threads.

By default, a Hashtable is ​​synchronized, so only one thread can access the table at a time.

​By default HashMap​ is not ​​synchronized, so ​chances are there for thread interference and memory consistency errors

Java throw and throws keywords

By Lokesh Gupta | Filed Under: Java Exception Handling

In Java exception handling, throw keyword is used to explicitly throw an exception from a method or constructor. And throws keyword is used declare the list of exceptions which may be thrown by that method or constructor.

1. Java throw keyword

1.1. Syntax

To throw an exception from a method or constructor, use throw keyword along with an instance of exception class.

1.2. Handling of checked vs unchecked exceptions

If we throw an unchecked exception from a method, it is not mandatory to handle the exception or declare in throws clause. For example, NullPointerException is an unchecked exception.

But if we throw a checked exception using throw statement, we MUST either handle the exception in catch block or method much explicitly declare it using throws declaration. For example, FileNotFoundException is a checked exception.

In Java, every subclass of Error and RuntimeException is an unchecked exception. A checked exception is everything else under the Throwable class.

1.3. Exception propagation

An exception propagates from method to method, up the call stack, until it’s caught. So if a() calls b(), which calls c(), which calls d(), and if d() throws an exception, the exception will propagate from d to c to b to a, unless one of these methods catches the exception.

The search for exception handler begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called, as described above.

When an appropriate handler (catch block) is found, the runtime system passes the exception to the handler. If no exception handler is found then exception reaches to JVM’s default exception handler which prints the exception details to logs and terminate the application.

2. Java throws keyword

Java throws keyword is used to declare a list of exceptions that may occur during the method execution.

2.1. Syntax

To declare the list of exceptions, use throws keyword along with exception class names.

2.2. Can throw checked and unchecked exceptions

We can declare both types of exceptions using throws clause i.e. checked and unchecked exceptions. But the method calling the given method must handle only checked exceptions. Handling of unchecked exceptions is optional.

3. Difference between throw and throws in Java

  1. throw keyword is used to throw a single exception explicitly from any method or constructor while throws keyword is used in method and constructor declaration, denoted which exception can possible be thrown by this method.
  2. throw is followed by an instance of exception class while throws is followed by exception class name.
  3. throw is used within the method and constructor where as throws is used with the method and constructor signature.
  4. We can throw only single exceptions using throw but we can declare multiple exceptions using throws one of which may or may not throw by method.
  5. A checked exception is propagated to the caller method, while unchecked exceptions are not propagated thus may not require explicit exception handling.
  6. Using throw keyword we can also break a switch statement or a loop without using break keyword which cannot be performed using throws.

About Lokesh Gupta

A family guy with fun loving nature. Love computers, programming and solving everyday problems. Find me on Facebook and Twitter.

This statement is wrong
“For example, FileNotFoundException is an unchecked exception.” Can you please correct it

That was a typo. Thanks for reporting it. Much appreciated !!

“A checked exception is propagated to the caller method, while unchecked exceptions are not propagated thus may not require explicit exception handling.”

This is quite not correct.

The unchecked exception in fact does propagate through the method call stack and is being handled whenever it finds an explicit handler or propagates to the JVM and is being handled by the default JVM exception handler.

Checked exceptions do not propagate. And as a result, this has to be explicitly mentioned/declared to the caller method in the call stack using throws keyword. It is a declaration to the caller method to provide a handler or propagate it to the next caller in the stack using the throws keyword. Even if the exception needs to be propagated to the JVM to be handled by default handler, you have to explicitly define/declare the Exception being thrown.

Читать еще:  Стандартная ошибка уравнения регрессии

Both unchecked and checked exception does occur at runtime. If you compile code with the lines :
FileInputStream inputStream = new FIS(new File(“”);

The compiler only checks if you have handled the Exception/declared the exception. There is no way compiler knows if the file exists/not and there will be an IOException.

I think I reason behind the names checked and unchecked exception comes from the way compiler checks if you have declared all your exceptions which do not propagate (IOException/SQLException) and don’t check the ones which automatically propagate(RuntimeException). It is designed in a way where the compiler can pre-check the fact that checked exceptions can propagate.

Java exception in constructor

In this article, we’ll cover the process of creating custom both checked and unchecked exceptions in Java.

If you’d like to read more about exceptions and exception handling in Java, we’ve covered it in detail in — Exception Handling in Java: A Complete Guide with Best and Worst Practices

Why Use Custom Exceptions?

Although Java exceptions, as they are, cover nearly all exceptional cases and conditions, your application might throw a specific custom exception, unique to your code and logic.

Sometimes, we need to create our own for representing business logic exceptions, i.e. exceptions that are specific to our business logic or workflow. For example EmailNotUniqueException , InvalidUserStateException , etc.

They help application clients to better understand what went wrong. They are particularly useful for doing exception handling for REST APIs as different business logic constraints require different response codes to be sent back to the client.

If defining a custom exception doesn’t provide benefit over using a regular exception in Java, there’s no need to define custom exceptions and you should just stick to the ones that are already available — no need to invent hot water again.

Custom Checked Exception

Let’s consider a scenario where we want to validate an email that is passed as an argument to a method.

We want to check whether it’s valid or not. Now we could use Java’s built-in IllegalArgumentException , which is fine if we are just checking for a single thing like whether it matches a predefined REGEX or not.

But suppose we also have a business condition to check that all emails in our system need to be unique. Now we have to perform a second check (DB/network call). We can, of course, use the same IllegalArgumentException , but it will be not clear what the exact cause is — whether the email failed REGEX validation or the email already exists in the database.

Let’s create a custom exception to handle this situation. To create an exception, like any other exception, we have to extend the java.lang.Exception class:

Note that we provided a constructor that takes a String error message and calls the parent class constructor. Now, this is not mandatory but it’s a common practice to have some sort of details about the exception that occurred.

By calling super(message) , we initialize the exception’s error message and the base class takes care of setting up the custom message, according to the message .

Now, let’s use this custom exception in our code. Since we’re defining a method that can throw an exception in the service layer, we’ll mark it with the throws keyword.

If the input email already exists in our database (in this case a list), we throw our custom exception:

Now let’s write a client for our service. Since it’s a checked exception, we have to adhere to the handle-or-declare rule. In the proceeding example, we decided to «handle» it:

Running this piece of code will yield:

Note: The exception handling process is omitted for brevity but is an important process nonetheless.

Custom Unchecked Exception

This works perfectly fine but our code has become a bit messy. Additionally, we are forcing the client to capture our exception in a try-catch block. In some cases, this can lead to forcing developers to write boilerplate code.

In this case, it can be beneficial to create a custom runtime exception instead. To create a custom unchecked exception we have to extend the java.lang.RuntimeException class.

Let’s consider the situation where we have to check if the email has a valid domain name or not:

Now let use it in our service:

Notice that we did not have to use the throws keywords at the method signature since it is an unchecked exception.

Now let’s write a client for our service. We don’t have to use a try-catch block this time:

Running this piece of code will yield:

Note: Of course, you can surround your code with a try-catch block to capture the arising exception but now it’s not being forced by the compiler.

Rethrowing an Exception Wrapped Inside a Custom Exception

Sometimes we need to catch an exception and re-throw it by adding in a few more details. This is usually common if you have various error codes defined in your application that needs to be either logged or returned to the client in case of that particular exception.

Suppose your application has a standard ErrorCodes class:

Let’s create our custom exception:

Notice we have multiple constructors and let the service class decide which one to use. Since we are rethrowing the exception, it’s always a good practice to capture the root cause of the exception hence the Throwable argument which can be passed` to the parent class constructor.

We are also capturing the error code in one of the constructors and set the errorCode within the exception itself. The errorCode could be used by the client for logging or any other purpose. This helps in a more centralized standard for exception handling.

Lets write our service class:

So we caught the standard NumberFormatException and threw our own InvalidCurrencyDataException . We passed the parent exception to our custom exception so that we won’t lose the root cause from which they occurred.

Let’s write a test client for this service:

As you can see we have a nice stack-trace of the exception which could be useful for debugging purposes.

Best Practices for Custom Exceptions

  • Adhere to the general naming convention throughout the Java ecosystem — All custom exception class names should end with «Exception»
  • Avoid making custom exceptions if standard exceptions from the JDK itself can serve the purpose. In most cases, there’s no need to define custom exceptions.
  • Prefer runtime exceptions over checked exceptions. Frameworks like Spring have wrapped all checked exception to runtime exceptions, hence not forcing the client to write boilerplate code that they don’t want or need to.
  • Provide many overloaded constructors based on how the custom exception would be thrown. If it’s being used for rethrowing an existing exception then definitely provide a constructor that sets the cause.
Читать еще:  Java security nosuchalgorithmexception

Conclusion

Custom exceptions are used for specific business logic and requirements. In this article, we’ve discussed the need for them as well as covered their usage.

The code for the examples used in this article can be found on Github.

Constructor Exceptions in C++, C#, and Java

I just received the following question, whose answer is the same in C++, C#, and Java.

Question: In the following code, why isn’t the destructor/disposer ever called to clean up the Widget when the constructor emits an exception? You can entertain this question in your mainstream language of choice:

public:
Gadget() <
w = new Widget();
throw new exception();
// … or some API call might throw
>;

Gadget() <
if( w != nullptr ) delete w;
>
>;

public Gadget() <
w = new Widget();
throw new Exception();
// … or some API call might throw
>;

public void Dispose() <
// … eliding other mechanics, eventually calls:
if( w != null ) w.Dispose();
// or just “w = null;” if Widget isn’t IDisposable
>
>;

public Gadget() <
w = new Widget();
throw new Exception();
// … or some API call might throw
>;

public void dispose() <
if( w != null ) w.dispose();
// or just “w = null;” if Widget isn’t disposable

>
>;

Interestingly, we can answer this even without knowing the calling code… but there is typical calling code that is similar in all three languages that reinforces the answer.

Construction and Lifetime

The fundamental principles behind the answer is the same in C++, C#, and Java:

  1. A constructor conceptually turns a suitably sized chunk of raw memory into an object that obeys its invariants. An object’s lifetime doesn’t begin until its constructor completes successfully. If a constructor ends by throwing an exception, that means it never finished creating the object and setting up its invariants — and at the point the exceptional constructor exits, the object not only doesn’t exist, but never existed.
  2. A destructor/disposer conceptually turns an object back into raw memory. Therefore, just like all other nonprivate methods, destructors/disposers assume as a precondition that “this” object is actually a valid object and that its invariants hold. Hence, destructors/disposers only run on successfully constructed objects.

I’ve covered some of these concepts and consequences before in GotW #66, “Constructor Failures,” which appeared in updated and expanded form as Items 17 and 18 of More Exceptional C++.

In particular, if Gadget’s constructor throws, it means that the Gadget object wasn’t created and never existed. So there’s nothing to destroy or dispose: The destructor/disposer not only isn’t needed to run, but it can’t run because it doesn’t have a valid object to run against.

Incidentally, it also means that the Gadget constructor isn’t exception-safe, because it and only it can clean up resources it might leak. In the C++ version, the usual simple way to write the code correctly is to change the w member’s type from Widget* to shared_ptr or an equivalent smart pointer type that owns the object. But let’s leave that aside for now to explore the more general issue.

A Look At the Calling Code

Next, let’s see how these semantics are actually enforced, whether by language rules or by convention, on the calling side in each language. Here are the major idiomatic ways in each language to use an Gadget object in an exception-safe way:

<
Gadget myGadget;
// do something with myGadget
>

using( Gadget myGadget = new Gadget() )
<
// do something with myGadget
>

Gadget myGadget = new Gadget();

try <
// do something with myGadget
>
finally <
myGadget.dispose();
>

Consider the two cases where an exception can occur:

  • What if an exception is thrown while using myGadget — that is, during “do something with myGadget”? In all cases, we know that myGadget’s destructor/dispose method is guaranteed to be called.
  • But what if an exception is thrown while constructing myGadget? Now in all cases the answer is that the destructor/dispose method is guaranteed not to be called.

Put another way, we can say for all cases: The destructor/dispose is guaranteed to be run if and only if the constructor completed successfully.

Another Look At the Destructor/Dispose Code

Finally, let’s return to each key line of code one more time:

The motivation for the nullness tests in the original example was to clean up partly-constructed objects. That motivation is suspect in principle — it means the constructors aren’t exception-safe because only they can clean up after themselves — and as we’ve seen it’s flawed in practice because the destructors/disposers won’t ever run on the code paths that the original motivation cared about. So we don’t need the nullness tests for that reason, although you might still have nullness tests in destructors/disposers to handle ‘optional’ parts of an object where a valid object might hold a null pointer or reference member during its lifetime.

In this particular example, we can observe that the nullness tests are actually unnecessary, because w will always be non-null if the object was constructed successfully. There is no (legitimate) way that you can call the destructor/disposer (Furthermore, C++ developers will know that the test is unnecessary for a second reason: Delete is a no-op if the pointer passed to it is null, so there’s never a need to check for that special case.)

Conclusion

When it comes to object lifetimes, all OO languages are more alike than different. Object and resource lifetime matters, whether or not you have a managed language, garbage collection (finalizers are not destructors/disposers!), templates, generics, or any other fancy bell or whistle layered on top of the basic humble class.

The same basic issues arise everywhere… the code you write to deal with them is just spelled using different language features and/or idioms in the different languages, that’s all. We can have lively discussions about which language offers the easiest/best/greenest/lowest-carbon-footprint way to express how we want to deal with a particular aspect of object construction, lifetime, and teardown, but those concerns are general and fundamental no matter which favorite language you’re using to write your code this week.

Ссылка на основную публикацию
Adblock
detector