2013-04-20 3 views
5

У меня есть два конструктора для моего класса, один из которых принимает объект File, а другой принимает объект String, и я хочу использовать ключевое слово this. Функция с реализацией - это параметр с параметром File, а один с String вызовет this. Теперь я хочу проверить исключение в конструкторе, который принимает String, но я получаю ошибку, что this должна быть первой строкой. Как я могу проверить наличие ошибок, а затем позвонить this.Исключение обработки конструктора и использование этого ключевого слова Java

Вот мой код:

public Test (String filename) { 
    if (filename == null) 
     throw new NullPointerException("The String you entered is null."); 
    if (filename.isEmpty()) 
     throw new IllegalArgumentException("The String you entered is empty."); 

    this(new File(filename)); // error 
} 

public Test (File f) { 
    /* implementation here */ 
} 

Это точная ошибка: Constructor call must be the first statement in a constructor

+0

Какая ошибка вы получаете? – Thomas

+0

Код размещен прямо напротив того, что вы описали! – NINCOMPOOP

ответ

2

К сожалению, это невозможно в Java, благодаря их произвольных ограничений. У вас есть две основные возможности.

Более идиоматическая технология Java заключается в том, чтобы обернуть все в заводскую функцию, чтобы вы могли поймать исключение. Фабричные функции также полезны, поскольку они позволяют создавать объекты полиморфно и помогают скрыть детали того, какой объект фактически создан.

public static Test create(String filename){ 
    if (filename == null) 
     throw new NullPointerException("The String you entered is null."); 
    if (filename.isEmpty()) 
     throw new IllegalArgumentException("The String you entered is empty."); 
    return new Test(filename); 
} 

private Test (String filename) { 
    this(new File(filename)); 
} 

public Test (File f) { 
    /* implementation here */ 
} 

Другой вариант заключается в том, чтобы написать конструктор в байт-коде, где таких ограничений нет. К сожалению, байт-код менее читабельен и поддерживается, поэтому вы, вероятно, захотите минимизировать количество байт-кода в основном Java-приложении. Вы также можете сделать это на языке, отличном от Java, например AspectJ.

Редактировать: Если вы на самом деле не пытаетесь поймать исключения, то есть третья возможность. Вы можете вставить произвольный код перед вызовом супер-конструктора, создав отдельную функцию, которая выполняет проверки, а затем передает ее как фиктивный аргумент в вызов супер-конструктора. Поскольку аргументы сначала оцениваются, ваш код запускается первым, но это немного взломан.

public Test (String filename) { 
    this(doChecks(filename), new File(filename)); 
} 

private static Void doChecks(String filename){ 
    if (filename == null) 
     throw new NullPointerException("The String you entered is null."); 
    if (filename.isEmpty()) 
     throw new IllegalArgumentException("The String you entered is empty."); 
    return null; 
} 

public Test (Void dummy, File f) { 
    this(f); 
} 

public Test (File f) { 
    /* implementation here */ 
} 
+0

Первый вариант, как написать функцию 'init' и использовать его? –

+0

Я просто добавил пример кода для третьего варианта. – Antimony

+0

* Это невозможно в Java благодаря их произвольным ограничениям: я полагаю, что ограничения не являются произвольными;) – NINCOMPOOP

0

Нет, вы не можете проверить наличие ошибок перед вызовом this. Это запрещено в спецификации. На самом деле, вам это не нужно. Позвольте new File(filename) выбросить исключения.

редактировать: Я видел aizen92 свой комментарий: Actually that is what my constructor with the implementation has, it catches the exception may be thrown by file, so I just add the null exception and use this directly in my second constructor?

public Test (String filename) { 
    this((filename == null || filename.isEmpty()) ? null : new File(filename)); 
} 
+0

Это вызовет неправильный тип исключения, когда 'filename.isEmpty()'. – Antimony

0

В случае мы используем this или super в конструкторе, либо this или super должен быть первым оператором в конструкторе. Лучше, если вы выбрали исключение из определенного конструктора.

public Test (String filename) { 
    this(new File(filename)); 
} 

Пусть второй конструктор обрабатывать любое исключение, вызванное пропусканием null.

public Test (File file) { 
    // exception handling code 
    // or new instance creation 
} 
+0

На самом деле это то, что мой конструктор с реализацией имеет, он ловит исключение, может быть брошен файлом, поэтому я просто добавляю исключение null и использую 'this' непосредственно в моем втором конструкторе? –

Смежные вопросы