I don't understand why the compiler does not warn me about not catching or throwing an SQLException. Here's the situation:
I have defined this interface:
public interface GenericDatabaseManager {
public void createTables(DataBase model) throws SQLException;
}
Then I created this class that implements the given interface:
public class SqliteHelper extends SQLiteOpenHelper implements
GenericDatabaseManager {
#Override
public void createTables(DataBase model) throws SQLException {
// Code that throws SQLException
}
And finally I'm calling this SqliteHelper.createTables() from here:
public class DatabaseManager extends CoreModule {
private boolean createUpdateDB(final String dbString, final String appId) {
// Previous code...
if (oldVer == -1) {
dbCoreModel.addModel(dbModel);
dbCoreModel.getManager().createTables(dbModel);
return true;
}
// More code...
}
}
dbCoreModel.getManager() returns a GenericDatabaseManager instance. But the compiler shows no error on dbCoreModel.getManager().createTables(dbModel); line, although this line throws an SQLException.
Does anyone have an idea about why is this happening? Thanks in advance.
EDIT: about SQLException does not need to be catched because it's a RuntimeException. This is not true. Here's an example:
import java.sql.SQLException;
interface Interface {
public void throwsSQLException() throws SQLException;
}
class Test implements Interface {
#Override
public void throwsSQLException() throws SQLException {
throw new SQLException();
}
}
public class Main {
public static void main(String[] args) {
Interface i = new Test();
i.throwsSQLException();
System.out.println("Finished");
}
}
The compiler DOES show an error in i.throwsSQLException(); in this case.
android.database.SQLException is a runtime exception.
In java it is not necessary to catch or declare throws for runtime exceptions. Read a detailed description about RuntimeExceptions in java here
Related
I have my parent abstract JUnitTest class:
public abstract class RestWSTest
{
public RestWSTest()
{
}
#Before
public void setUp() throws Exception
{
...
}
#After
public void tearDown() throws Exception
{
...
}
}
Then I would like to have a class that extends RestWSTest, like this:
public class RestWSCreateGroupTest extends RestWSTest
{
public RestWSCreateGroupTest()
{
super();
}
#Before
public void setUp() throws Exception
{
super(); --> *Constructor call must be the first statement in a constructor*
...
}
#After
public void tearDown() throws Exception
{
super(); --> *Constructor call must be the first statement in a constructor*
...
}
#Test
public void testCreateGroup()
{
...
}
}
Why do I get the error message? I have a constructor and there I call super(), so I don't really know what to do...
The method public void setUp() is not a constructor. You can not call super(); inside it. I think you intend super.setUp();
You can't use the super() call outside the constructor methods.
In other words, setUp() and tearDown() are methods and they are NOT constrcutors, so you can't use super() call.
Rather, you can access/invoke the super class methods using the syntax: super.mySuperClassMethod();
So change your code as below:
public class RestWSCreateGroupTest extends RestWSTest
{
public RestWSCreateGroupTest()
{
super();
}
#Before
public void setUp() throws Exception
{
super.setUp();
...
}
#After
public void tearDown() throws Exception
{
super.tearDown();
...
}
#Test
public void testCreateGroup()
{
...
}
}
For more details refer the below link:
https://docs.oracle.com/javase/tutorial/java/IandI/super.html
Imagine you have a method like:
public void doGreatThings() throws CantDoGreatThingsException, RuntimeException {...}
Is there any way to programmatically get the declared thrown exceptions by way of reflection?
// It might return something like Exception[] thrownExceptions = [CantDoGreatThingsException.class, RuntimeException.class]
You can use getExceptionTypes() method. You will not get Exception[] since such array would expect exception instances, but you will get instead Class<?>[] which will hold all thrown exception .class.
Demo:
class Demo{
private void test() throws IOException, FileAlreadyExistsException{}
public static void main(java.lang.String[] args) throws Exception {
Method declaredMethod = Demo.class.getDeclaredMethod("test");
Class<?>[] exceptionTypes = declaredMethod.getExceptionTypes();
for (Class<?> exception: exceptionTypes){
System.out.println(exception);
}
}
}
Output:
class java.io.IOException
class java.nio.file.FileAlreadyExistsException
You can do that the reflection api.
// First resolve the method
Method method = MyClass.class.getMethod("doGreatThings");
// Retrieve the Exceptions from the method
System.out.println(Arrays.toString(method.getExceptionTypes()));
if the method requires parameters you need to supply them with the Class.getMethod() call.
Here's an example:
import java.io.IOException;
import java.util.Arrays;
public class Test {
public void test() throws RuntimeException, IOException {
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
System.out.println(Arrays.toString(Test.class.getDeclaredMethod("test").getExceptionTypes()));
}
}
I have this class:
public class SomeClass {
public void someMethod() {} throws someException
public class someException extends Exception { // Exception class
public someException(String message) {
super(message);
}
}
}
Another class:
public class SomeOtherClass {
public static void main (String[] args) {
SomeClass obj = new SomeClass();
try {
obj.someMethod();
} catch (someException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Eclipse complains that "someException cannot be resolved to a type". I tried to add
import SomeClass.someException
But then it says "The import SomeClass cannot be resolved"
You could of course put someException in a separate file, and not make it nested, is this the only way?
You should be able to use the class by qualifying it with the class name, SomeClass.someException. If you'd rather import it, you have to put your code in a package. You can then do:
import yourpkg.SomeClass.someException;
Also, you got the syntax a bit wrong here:
public void someMethod() {} throws someException
it should be
public void someMethod() throws someException {}
(But perhaps that was a typo in your question.)
You may also want to consider making the nested class static unless you really need to reference the enclosing object:
public static class someException extends Exception {
...
}
Consider the following code:
public interface I1 {
public void bar1() throws IOException;
}
public interface I2 extends I1 {
public void bar2() throws Exception;
}
public interface I3 {
public void bar3() throws Exception;
}
public abstract class A implements I2 {
public void bar2() throws Exception{};
public void bar3() throws Exception{};
protected abstract void bar4();
protected void bar5() {};
}
Now, I created a class, B as follows:
public class B extends A implements I3 {
#Override
protected void bar4() {}
public void bar1() {}
}
Why is the compiler letting me do that? I mean, shouldn't it be:
public void bar1() throws IOException;
When overriding you cannot throw Broader or newer exception. Not throwing a super class method's exception is allowed.
The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method. For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.
Inheritance lets you make functions more specific.
You can reduce the number of things you throw, you can return a subtype of the return type, you can accept a supertype of a parameter type.
This is because any possible call to your method most be a legal call to the super method, but the reverse does not need to be true.
In other words in your example:
new B().bar1()
You know it doesn't throw the exception, you don't need to catch.
((A)new B()).bar1()
You need to catch the exception as since you are now processing any A or subclass of A you might need to handle it.
If you tried to do the reverse though and create a class C:
public class C extends A implements I3 {
#Override
protected void bar4() {}
public void bar1() throws IOException, SomeOtherException {}
}
This would not be allowed as now if you tried to use a C as an A you are not going to be catching SomeOtherException.
I read this code where the interface throws an exception, but the class which implements it doesn't throw one or catch one, why is that? Is it legal or safe in java?
import java.rmi.*;
public interface MyRemote extends Remote {
public String sayHello() throws RemoteException;
}
import java.rmi.*;
import java.rmi.server.*;
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote{
public String sayHello() {
return "Server says, 'Hey'";
}
public MyRemoteImpl() throws RemoteException {}
public static void main (String[] args) {
try {
MyRemote service = new MyRemoteImpl();
Naming.rebind("RemoteHello", service);
} catch(Exception ex)
{
ex.printStackTrace();
}
}
}
A general rule of implementing and extending is you can make your new class or interface "less restrictive" but not "more restrictive". If you think of the requirement to handle an exception as a restriction, an implementation that doesn't declare the exception is less restrictive. Anybody who codes to the interface will not have trouble with your class.
— Stan James
As part of the discussion at http://www.coderanch.com/t/399874/java/java/Methods-throwing-Exception-Interface
If a Java method overrides another in a parent class, or implements a method defined in an interface, it may not throw additional checked exceptions, but it may throw fewer.
public class A {
public void thrower() throws SQLException {...}
}
public class B extends A {
#Override
public void thrower() throws SQLException, RuntimeException, NamingException {...}
}
SQLException is fine; it's declared in the overridden method. It could even be replaced by a subclass like SerialException.
RuntimeException is fine; those can be used anywhere.
NamingException is illegal. It isn't a RuntimeException, and isn't in A's list, even as a subtype.
Great answer by #Chetter Hummin.
One way to look at this, and I find it easy to remember, is interface's implementations can be more specific but not more general.
For example in interface void test() throws Exception means "test may throw exception"
then implementation can be void test() means "test will not throw exception" (more specific)
or implementation can be void test() throws NullpointerException (more specific)
interface x {
void testException() throws Exception;
}
public class ExceptionTest implements x {
#Override
public void testException() { //this is fine
}
////// or
#Override
public void testException() throws NullPointerException { // this is fine
}
}