Naja, aufpassen. Das hat mit der Entwicklung im Team nichts zu tun. Nur weil zb eine 3-Tier-Anwendung entwickelt wird, bedeutet dies nicht zwangsweise, dass daran mehr als eine Person arbeitet. Die Exceptions laufen ohnehin unabhängig davon.
Exceptions unter Java und C#
Prinzipiell ist hier vieles gleich implementiert. In beiden Sprachen werden die try-catch-finally-Blöcke unterstützt und natürlich haben beide auch eine komplette Hierarchie der Exceptions, sowie das Mapping einer Exception in eine andere Exception (unter C# -> InnerException).
Beide Sprachen erlauben das Auslesen des Stack-Traces. Aber nur unter Java kann er auch geändert werden.
Weiters deklarierst du in Java in der Signatur der Klasse oder der Methode welche Exceptions von der Klasse/Methode geworfen werden. In C# ist das nicht so. Die Gründe hierfür aus Sicht von Microsoft hab ich mal für euch rauskopiert, weils mir einfach zu blöd ist, das jetzt aus dem Kopf zu schreiben:
1. Versioning
2. Productivity and code quality
3. Impracticality of having class author differentiate between "checked" and "unchecked" exceptions
4. Difficulty of determining the correct exceptions for interfaces.
Versioning
If C# required exception specifications then versioning would be more difficult. Once a class is published with a given set of "throws" exceptions, nothing could ever be added to that set since it would invariably break every client. The clients would be missing either a catch clause for the new exception or a matching "throws" declaration.
Not being able to change implementations to deal with new exceptional conditions drastically limits how class libraries can evolve, and thereby unnecessarily constrains real-world projects with long time spans. As an example, consider a class that exposes a function which doesn't throw any exceptions in its first version. Later, a new exceptional condition is found. The class author must choose between two unattractive options: catch and ignore the exception, or break compatibility.
Productivity and code quality
Examination of small programs leads to the conclusion that requiring exception specifications could both enhance developer productivity and enhance code quality, but experience with large software projects suggests a different result; decreased productivity and little or no increase in code quality.
Requiring exception specifications decreases developer productivity because of the sheer proliferation of exception specifications. This proliferation proceeds in two dimensions:
1. First, the number of members is generally monotonically increasing over time. That is, modern exception handling allows a division of work between the code that raises the exception and the code that handles it. These pieces of code may be separated by intervening code. For example, A calls B, B calls C, C calls D, and D raises an exception that is eventually handled by A. If C# required exception specifications, then each of A, B, C, and D would have to contain exception-handling related code even though only A and D do any actual work related to the exception.
2. The number of possible exceptions. The number of exceptions is unquestionably large. Any code that adds two numbers could result in an overflow exception, any code that divides two numbers could result in a divide by zero exception, and any code that instantiates an object could result in an out of memory exception.
The lack of an increase in code quality is related to the response of developers to the proliferation of exception specifications. Developers who carefully examine all of the exception specification errors reported by the compiler might see an increase in code quality, but this would come at the expense of productivity. A single new exceptional condition could result in the need to update hundreds of exception specifiers throughout the program. On the other hand, a less thorough developer has several available options that are far cheaper but also far less likely to increase code quality:
1. Reuse an existing exception for a purpose that doesn't quite fit.
2. Catch the exception and ignore it. This is obviously dangerous.
3. As a matter of practice, add a generic exception specification to each and every member, thus subverting the feature completely.
4. Mindlessly add whatever exception specifications the compiler requires. (For better or worse, automation of this process is inevitable.)
Each of these options has a low but non-zero implementation cost, and none are likely to increase code quality. This is not a pretty cost-benefit picture.
A better strategy is for client code, that is, code that is using a class library, to include both generic exception handling and specific exception handling. Generic exception handling is performed centrally, and generically deals with all exceptions. Specific exception handling checks for a smaller number of exceptions; the ones that the client code is specifically prepared to respond to or recover from. This split between generic and specific exception handlers is practically required since some exceptions (e.g., out of memory exceptions) can occur in many program locations but are rare in frequency. All client code needs to have some generic exception handling.
For another discussion of this point, take a look at:
http://www.mindview.net/Etc/Discussions/CheckedExceptions
Impracticality of having class author differentiate between "checked" and "unchecked" exceptions
Some systems allow a developer of a class to differentiate between "checked" exceptions (those that are enforced by the compiler) and "unchecked" exceptions (those that are not). In such systems, to make a decision about whether to employ a checked or unchecked exception, a class author would have to judge whether a given exception can occur throughout a given program and whether recovery from the exception is possible. We think that this is an impossible decision to make since these factors are primarily dependent on the code that is using the class rather than the class itself.
Difficulty of determining the correct exceptions for interfaces
Checked exceptions require that interface methods define which exceptions that may throw. If an interface method throws a limited set of exceptions, that places a constraint on interface implementers to use that same set.
This can present a problem if a specific implementation calls methods that throw exceptions that are not in the interface definition. The implementation must do something to get his code to compile, and there are several options:
1. Throw an unchecked exception from the implementation
2. Catch the exception, and throw one that the interface defines
3. Wrap the exception in one that the interface defines
4. Create an exception that derives from an exception the interface defines.
5. Swallow the exception
None of these workarounds are without problems. Using an unchecked exception or one that the interface does throw may not be appropriate. Wrapping the exception or creating a derived exception may work, but both hide information about what really happened from the user. Swallowing the exception is also a bad idea.