Назначение конечного поля в блоке try-catch внутри конструктора

Итак, я пытаюсь инициализировать DatagramSocket в конструкторе, и я хочу, чтобы это поле было final, но мой компилятор (т.е. Eclipse) выдает мне следующую ошибку:

Пустое конечное поле datagramSocket возможно, не было инициализировано

Это понятно. Вот фрагмент кода:

    public class Foo
    {
        private final int DEFAULT_UDPLISTENPORT = 49400;
        private final DatagramSocket datagramSocket;

        public Foo()
        {
            synchronized(this)
            {
                try
                {
                    datagramSocket = new DatagramSocket(DEFAULT_UDPLISTENPORT);
                }
                catch (SocketException e)
                {
                    // Log error
                    logger.error("Trouble opening UDP port: ", e);
                }
            }
        }
    }

Теперь, я знаю, что есть способ обойти это, но он требует создания временной переменной. Вот фрагмент кода:

    public class Foo
    {
        private final int DEFAULT_UDPLISTENPORT = 49400;
        private final DatagramSocket datagramSocket;

        public Foo()
        {
            synchronized(this)
            {
                DatagramSocket tempSocket = null;
                try
                {
                    tempSocket = new DatagramSocket(DEFAULT_UDPLISTENPORT);
                }
                catch (SocketException e)
                {
                    // Log error
                    logger.error("Trouble opening UDP port: ", e);
                }

                datagramSocket = tempSocket;
            }
        }
    }

Итак, я полагаю, мой вопрос в том, есть ли более элегантный способ сделать это, или это то, с чем мне придется жить, если я хочу, чтобы это поле было окончательным?

EDIT:

Для тех из вас, кто заинтересован, вот решение, которое я придумал на основе ваших рекомендаций:

public class Foo
{
    private static final Foo INSTANCE;
    static
    {
        try
        {
            INSTANCE = new Foo();
        }
        catch (SocketException e)
        {
            throw new ExceptionInInitializerError(e);
        }
    }
    private final int DEFAULT_UDPLISTENPORT = 49400;
    private final DatagramSocket datagramSocket;

    public Foo() throws SocketException
    {
        synchronized (this)
        {
            datagramSocket = new DatagramSocket(DEFAULT_UDPLISTENPORT);
        }
    }

    public static Foo getInstance()
    {
        return INSTANCE;
    }
}

Пожалуйста, дайте мне знать, если это правильно, или если у вас есть какие-либо другие предложения. Я ценю помощь!

7
задан mre 2 May 2011 в 15:09
поделиться