Results 1 to 10 of 10
  1. Default [Programming] Am I the only one...?


    Everywhere I look in Java code I always see try/catch exceptions. Don't you think this is poor programming? The programmer should be able to come up with any exception that the program might run across and program against those things happening, not to have a try/catch exception which can result in buggy, unpredictable code.

    Why use a try/catch when you can use if-elseif? What's the advantage to using try/catch, and why do I see so many try/catch exceptions in Java programming?

  2. DUCKS
    IGN: Mondays
    Server: Bellocan
    Level: 170
    Job: White Knight
    Guild: Affinity
    Alliance: Honour
    norway

    Default


    I never see THAT many try/catch-expressions in java-code. Mind putting some up?

    It's not necessarily bad code, efficient-wise. It's just ugly. Instead of throwing an error, you should rather just return null. But well, for type-specified languages, that turns out to be rather hard. I consider it as a workaround.

    I really hate Python at dictionaries there though. dict[key] raises KeyError when key is missing. asdf.

  3. Default


    There's a way around that.

    value = dict.get(keyName, defaultValue)

    So...

    Dict = {'1':'my value'}
    value = Dict.get('1', 'NULL') #Returns 'my value'
    value = Dict.get('2', 'NULL') #Returns 'NULL'

    Or you can do...

    Code:
    if key in Dict:
       #Do something
    else:
       #do something else
    No try/except required. :)

    ALL Python code I write has try/catch exceptions as a last resort because I consider it to be poor programming.

  4. Default


    I haven't gotten so far in my java class to get to try/catch coding yet...

    Is it that ugly?
    Maybe with my limited knowledge of coding, it doesn't seem too bad...

  5. Default


    Java has checked exceptions, which means that every method has to declare which exceptions it can possibly throw and the compiler will enforce that the list is not missing anything by seeing what exceptions methods that are called can throw and which of those are caught. This is generally regarded as a bad decision, and no other language I know of has checked exceptions, including C#, the "better Java", which made a conscious decision not to enforce what exceptions you say your method can throw (which you can and should say in a doc-comment).

    Suppose your method calls a method that takes a single int as a parameter and can throw ArgumentException if the number is negative. You know that your code never passes a negative number (maybe it even passes a literal int), but Java would still force you to either catch the exception or declare that your method can throw ArgumentException (or just Exception).

    I think what you're getting at is things that the programmer can check for before calling a method. When that's possible, you're right, that's preferred over blindly calling and catching an exception. But that's not always possible. For example, opening a file. Even if you check whether the file exists before trying to open it, it could get deleted between the time you check and the time you try to open it.

    When used correctly, exceptions eliminate the need to check the return value of every function that can have something go wrong. Sometimes the calling function doesn't know what to do about an error and the best thing to do is to let it propagate up and let some other function decide what to do. Exceptions also free the return value of a function to be used for useful information instead of an error status or a mixture of error status and information. In C++, destructors get called automatically as the stack unwinds when an exception occurs. This allows you to free resources automatically and avoid resource leaks. Other languages accomplish the same thing with finally blocks. If you're using return codes, cleanup can get pretty ugly.

    Catching an exception and not doing anything about it is often but not always bad practice. Empty catch blocks should be documented saying why you're ignoring the exception.

    The exceptions that can leave a method should match its level of abstraction. For example, a method that uses a cache file internally that callers do not "know about" should not throw a FileNotFoundException.

    Edit: Finally, exceptions are not always the best way to signal an error. If it's something that's somewhat expected to occur and that the caller almost certainly will check for, then using an error return value or an output parameter would be more appropriate. For example, C# has int.TryParse(string s, out int result) which should be used instead of int.Parse(string s) when parsing a string from the user.

    Did I miss anything? :P </wall of text>
    Last edited by Spaz; 2009-09-30 at 07:56 PM.

  6. DUCKS
    IGN: Mondays
    Server: Bellocan
    Level: 170
    Job: White Knight
    Guild: Affinity
    Alliance: Honour
    norway

    Default


    Oh, I know. But dict[key] should return null/nil when key's not found! :(

    Also...

  7. Default


    You could create your own wrapper class to make it perform how you want. For example, I created this wrapper class for file objects and I use it EVERYWHERE:

    Code:
    class IOStream:
        __slots__ = ['stream', 'mode', 'IODescriptor', 'EOF']
        def __init__(self, stream = '', mode = ''):
            self.name = ''
            self.mode = ''
            self.EOF = 0
            if stream != '' and mode != '':
                self.fopen(stream, mode)
    
        def fopen(self, stream, mode=None):
            if mode == None:
                raise Exception("Mode must be explicitly stated.")
            if mode == 'string':
                self.IODescriptor = cStringIO.StringIO(stream)
                self.name = 'cStringIO instance'
            else:
                self.IODescriptor = open(stream, mode)
                self.name = stream
            self.mode = mode
            self.GetEOF()
    
        def GetEOF(self):
            Remember = self.IODescriptor.tell()
            self.IODescriptor.seek(0, 2)
            self.EOF = self.IODescriptor.tell()
            self.IODescriptor.seek(Remember, 0)
    
        def tell(self):
            return self.IODescriptor.tell()
    
        def seek(self, offset, whence = 0):
            self.IODescriptor.seek(offset, whence)
    
        def read(self, numbytes = 0):
            if numbytes != 0:
                return self.IODescriptor.read(numbytes)
            else:
                return self.IODescriptor.read()
    
        def readfile(self, name):
            self.IODescriptor = open(name, 'rb')
            text = self.IODescriptor.read()
            self.IODescriptor.close()
            return text
    
        def write(self, whattowrite):
            self.IODescriptor.write(whattowrite)
    
        def close(self):
            self.IODescriptor.close()
    
        #READ BINARY NUMBER
        def rBool(self):
            return struct.unpack('?', self.IODescriptor.read(1))[0]
    
        def rU8(self):
            return struct.unpack('B', self.IODescriptor.read(1))[0]
    
        def rS8(self):
            return struct.unpack('b', self.IODescriptor.read(1))[0]
    
        def rU16(self):
            return struct.unpack('H', self.IODescriptor.read(2))[0]
    
        def rS16(self):
            return struct.unpack('h', self.IODescriptor.read(2))[0]
    
        def rU32(self):
            return struct.unpack('I', self.IODescriptor.read(4))[0]
    
        def rS32(self):
            return struct.unpack('i', self.IODescriptor.read(4))[0]
    
        def rU64(self):
            return struct.unpack('Q', self.IODescriptor.read(8))[0]
    
        def rS64(self):
            return struct.unpack('q', self.IODescriptor.read(8))[0]
    
        def rF32(self):
            return struct.unpack('f', self.IODescriptor.read(4))[0]
    
        def rF64(self):
            return struct.unpack('d', self.IODescriptor.read(8))[0]
    
        #BIG ENDIAN
        def rBool(self):
            return struct.unpack('?', self.IODescriptor.read(1))[0]
    
        def rbU8(self):
            return struct.unpack('!B', self.IODescriptor.read(1))[0]
    
        def rbS8(self):
            return struct.unpack('!b', self.IODescriptor.read(1))[0]
    
        def rbU16(self):
            return struct.unpack('!H', self.IODescriptor.read(2))[0]
    
        def rbS16(self):
            return struct.unpack('!h', self.IODescriptor.read(2))[0]
    
        def rbU32(self):
            return struct.unpack('!I', self.IODescriptor.read(4))[0]
    
        def rbS32(self):
            return struct.unpack('!i', self.IODescriptor.read(4))[0]
    
        def rb64(self):
            return struct.unpack('!Q', self.IODescriptor.read(8))[0]
    
        def rb64(self):
            return struct.unpack('!q', self.IODescriptor.read(8))[0]
    
    
        def rPackNum(self):
            value = self.rS8()
            if value == -128:
                return self.rS32()
            else:
                return value
    And Spaz... checked exceptions? You serious? Java requires that programmers have to code against certain exceptions when performing certain acts? Seems like unneeded boilerplate. I guess that's why I prefer C# over Java. Java does not play nice with binary, unsigned types, and now checked exceptions. Ugh.

  8. Default


    There are pros and cons to Exception, and personally, I think Java overkilled it.

    Tho, that is not necessarily a bad thing. It forces you to be aware of "issues". If we're going back to the PNG class and ImageStream interface we talked before, lets look at a few scenarios.

    1 - the function get_data in ImageStream failed to return the correct data. Sure you can code the function to have a massive if elseif else statement to govern all the possible cases, but it's an Interface, so each implementation has to carry out this task independently.

    If you turn it into an abstract class, that would solve the implementation issues, where only one implementation exists, however you're losing out on extending, because you can only extends once.

    Alternatively, you can apply a decorator/observer to the ImageStream, to handle errors.

    2 - you want customized error messages. In many situations, you will face an issue of how much information to display. Say you're using the above code to generate an image on the fly for sp.net users to view. Surely if something goes wrong, you want to tell them that it has "Failed to display the requested image", but tell yourself (in an error log file) that "OMG line xxx has a bad byte in it so I cant get the data out of file yyy after executing function zzz" etc to help you debug more.

    You may jump at the gun and think "INHERITANCE", but you're effectively entangle more of your code unnecessarily. Alternatively, you may want to use printf to control the format, or have the error writes to a stream, but again, extra weight.

    This is where exception comes handy. Coding logic should be "code to work, branch out errors". In OOP, Exceptions are vital when used correctly. In the first scenario, you can return appropriate exceptions per error or error groups. This ensures that the code does its checking. Tho you're still facing extends only 1 class issue. Once received an exception, the caller may choose to either throws it further up or digests it. Whether it be a log, or how much to display, etc, the decision is up to the caller, which is how it should be.

    If you take the MVC framework for example, the Model can run the business logic, and throws out either a result or an exception, which the controller receives and asks the view to render the appropriate display. Without exception, the Model must always keep its state in a pair {success/failure, data/error}, and the controller must check for it all the times.

    Further more, you will need to define your own error code, and have the view anticipates this flag as well, to display customised errors. This is seen regularly in C codes.

    tl;dr;

    Exception is an advanced form of error handling.

  9. Default


    Well, I really only use try/catch for Java when it forces me to. For example, whenever I'm using IO shyts. I didn't really tell the code to do anything other than error.printStackTrace(); if it turns out an IOException, which to me says "very serious problem with ur hardwarez", and the only one where I have extensive "else" stuff for error catching is when for whatever reason an image file with an illegal name was attempted to be written.

    But yeah, other than dealing with IO, I almost never do try/catch stuff since I'm wary of crazy crap happening in the realm of errors. Funny stuff already happens with me running flash games (rebooting FF usually resolves them), I don't need to see more mystery errors.

  10. Default


    You need to remember that all exceptions thrown that aren't OutOfMemoryError, StackOverflowError, NullPointerException and the like are not thrown by the JVM, but by the classes that come with Java.

    Plus Exceptions provide an easy way to give error descriptions. For example if there were a problem reading from disk due to corrupted sector.

    Would you rather say "Error reading from disk." or "Error reading from disk: corrupted sector"?

    I'd choose the latter.

    Throwing an exception is better and provides more information for the programmer and end-user. Just returning null.. eh, no thank you.

    At least in Java and most languages you are restricted to throwing only some type.

    In C++ you can throw ints, strings, objects, null, etc

    No joke.

    In the end it's all up to your style. For me, I would check for simple things such as invalid user input and stuff before executing. If an exception occurs, then something really bad happened. :)

    Try-catch does not end up in buggy or unpredictable code. And some exceptions can't be avoided. Try-catch is not poor programming.

  11.  

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •