fad*_*bee 13 java constructor checked-exceptions
我有一些丑陋的代码,想要重构它:
public class UdpTransport extends AbstractLayer<byte[]> {
private final DatagramSocket socket;
private final InetAddress address;
private final int port;
/* boolean dead is provided by superclass */
public UdpTransport(String host, int port) {
this.port = port;
InetAddress tmp_address = null;
try {
tmp_address = InetAddress.getByName(host);
} catch (UnknownHostException e) {
e.printStackTrace();
dead = true;
socket = null;
address = null;
return;
}
address = tmp_address;
DatagramSocket tmp_socket = null;
try {
tmp_socket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
dead = true;
socket = null;
return;
}
socket = tmp_socket;
}
...
Run Code Online (Sandbox Code Playgroud)
导致丑陋的问题是final成员之间的互动和捕获的异常.final如果可能的话,我想保留会员.
我想形成如下代码,但Java编译器无法分析控制流 - 没有办法address可以第二次分配,因为第一次尝试的赋值必须抛出控制才能达到该catch子句.
public UdpTransport(String host, int port) {
this.port = port;
try {
address = InetAddress.getByName(host);
} catch (UnknownHostException e) {
e.printStackTrace();
dead = true;
address = null; // can only have reached here if exception was thrown
socket = null;
return;
}
...
Run Code Online (Sandbox Code Playgroud)
Error:(27, 13) error: variable address might already have been assigned
有什么建议?
PS我有一个约束,即构造函数不会抛出 - 否则这一切都很容易.
h22*_*h22 13
让构造函数抛出异常.离开final未分配是确定的,如果在构造函数不正常终止,在此情况下,不返回任何对象.
代码中最丑陋的部分是在构造函数中捕获异常,然后返回现有但无效的实例.
如果您可以自由使用私有构造函数,则可以将构造函数隐藏在公共静态工厂方法后面,该方法可以返回UdpTransport类的不同实例.让我们说:
public final class UdpTransport
extends AbstractLayer<byte[]> {
private final DatagramSocket socket;
private final InetAddress address;
private final int port;
/* boolean dead is provided by superclass */
private UdpTransport(final boolean dead, final DatagramSocket socket, final InetAddress address, final int port) {
super(dead);
this.socket = socket;
this.address = address;
this.port = port;
}
public static UdpTransport createUdpTransport(final String host, final int port) {
try {
return new UdpTransport(false, new DatagramSocket(), getByName(host), port);
} catch ( final SocketException | UnknownHostException ex ) {
ex.printStackTrace();
return new UdpTransport(true, null, null, port);
}
}
}
Run Code Online (Sandbox Code Playgroud)
上述解决方案可能包含以下注意事项:
final字段.这非常类似于我记得在C#和Scala中称为主要构造函数的东西.UdpTransport实例化的复杂性.socket并address设置为实例,或者设置为null指示无效状态.因此,此实例状态可能与您的问题中的代码生成的状态略有不同.public static AbstractLayer<byte[]> createUdpTransport(final String host, final int port)注意返回类型).这种方法的强大之处在于,除非使用UdpTransport特定的公共接口,否则可以根据需要用任何子类替换返回的值.-1可以指示无效的端口值,或者Integer如果您可以自由使用,则甚至可以为空更改类的字段和原始包装器不是对你的限制):private static final AbstractLayer<byte[]> deadUdpTransport = new UdpTransport(true, null, null, -1);
...
public static AbstractLayer<byte[]> createUdpTransport(final String host, final int port) {
try {
return new UdpTransport(false, new DatagramSocket(), getByName(host), port);
} catch ( final SocketException | UnknownHostException ex ) {
ex.printStackTrace();
return deadUdpTransport; // it's safe unless UdpTransport is immutable
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1503 次 |
| 最近记录: |