简体   繁体   中英

How and where do you define your own Exception hierarchy in Java?

How and where do you define your own Exception hierarchy in Java?

My main question concerns package location where your Exception classes must be defined.

Do we create a special package for our exceptions and put all classes inside it?

I use this as a general rule.

  • Where it makes sense, use a pre-defined Java exception. For example, if your code has some sort of I/O Error, it is fine to throw an IOException.
  • Only use exception hierarchies if you need to differentiate between the two exceptions in a try/catch block. A lot of times it is perfectly fine to have a single component throw a single exception type with different messages for different errors. If the user cannot really do anything to handle the error specially, use the same generic exception class. If the user is able to handle them differently, that is when you should use a hierarchy.
  • For hierarchies, do not make all exceptions from different components inherit from a base exception. There is no real reason to do this. If the consumer wants to catch anything, they can simply catch Exception.
  • For package location, I put an Exception class with the code it relates to. So if I have a BusinessService in a package abc, I have a abcBusinessException to go with it. I'm not a fan of putting all exceptions into an exceptions package. It just makes it hard to find.

I put all of my custom exceptions into a com.company.project.exception package. I do this rather than putting them "close" to the locations where they crop up.

Here's my reasoning: If a given exception is only cropping up within one or two service classes somewhere, it may not be a general enough exception to deserve its own class. Only if I see a common theme popping up in multiple places will I go to the trouble of creating a custom Exception class. And if it is popping up in multiple places, then there's no logical package to "attach" it to, so an exception-specific package seems like the right way to go.

You can create your Exception classes wherever you want.

The important thing is to extend an existing Exception class ( java.lang.Throwable in fact). For instance java.lang.Exception or java.lang.RuntimeException . The first is a checked exception while extending RuntimeException will result in an unchecked exception; the differences between the two are detailed here .

对于用户定义的Exception类应该放入哪些包,语言没有规定任何要求。只要类扩展java.lang.Throwable ,就可以抛出。

To answer the main question,

Q : Do we create a special package for our exceptions and put all classes inside it?

I would discourage this.

What is a package as it says in the Oracle docs ,

A package is a namespace that organizes a set of related classes and interfaces . Conceptually you can think of packages as being similar to different folders on your computer. You might keep HTML pages in one folder, images in another, and scripts or applications in yet another. Because software written in the Java programming language can be composed of hundreds or thousands of individual classes, it makes sense to keep things organized by placing related classes and interfaces into packages .

A custom exception is also a Java class. And it should be organized among the other related classes and interfaces. The relatedness should not be decided based on whether it's an Exception or not, it should be decided based on what it is doing, or the purpose of its existence.

For an example assume you are working in a management system and have a package that deals with a back-end API to retrieve employee records. In case if you fail to retrieve a record to a given employee ID, and if you have a specific needs to handle this specific scenario up in the hierarchy it's okay to define a custom exception that says, EmployeeRecordNotFoundException.

public class EmployeeRecordNotFoundException extends Exception {
    // constructors ... etc ...
}

Then you can place this class in the same package as the Class where you are going to use it.

com.abc_org.management.employee_management
    EmployeeDetailsRetriever
    NewEmployeeCreater
    EmployeeRecordNotFoundException // place it where it belongs
    EmployeeIDValidator  // <- TIP : don't make utility classes as well, make class that do the utility function and make that class do only that specific thing
com.abc_org.management.customer_management
    // no class in here is going to use EmployeeRecordNotFoundException
    // so no point of making that available to this as well
com.abc_org.management.exception
    // no point of creating this

It doesn't make sense to make it defined in a more global level since no other class is going to access it as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM