Python有一个很好的功能:" with"声明。它对于进行影响语句中调用的所有代码的全局更改非常有用。
e.g。你可以定义一个CapturePrintStatements类来捕获"中所有打印的语句,用"
with CapturePrintStatements() as c:
print 'Stuff Done'
print 'More Stuff Done'
assert c.get_text() == 'Stuff Done'
Java中是否有等价物?
答案 0 :(得分:6)
try-with-resources是它的Java等价物,可以在Java 7及更高版本中使用。
这使您可以使用需要明确关闭的资源,而无需担心关闭它们。例如:
在Java7之前:
InputStream input = null;
try {
input = new FileInputStream("myFile.txt");
} finally {
if(input != null){
input.close();
}
}
Java 7&起来:强>
try(FileInputStream input = new FileInputStream("myFile.txt")) {
// Do something with the InputStream
}
这是 try-with-resources 构造。当执行流程超出try
块时,FileInputStream
将自动关闭。这是因为FileInputStream
实现了AutoCloseable
接口。
答案 1 :(得分:4)
正如穆罕默德所说,你可以使用try-with-resources。在这种情况下,您希望拥有自己的资源,并不是很难做到。
首先,您的班级应该实施AutoCloseable
:
public class CaptureOutput implements AutoCloseable {
构建此类时,您应该
System.out
,PrintStream
来替换它(参见Java: PrintStream to String?)和System.setOut()
替换默认流。以下是我们的工作方式
public CaptureOutput() {
this.stream = new ByteArrayOutputStream();
this.out = System.out;
System.setOut(new PrintStream(stream));
}
秘密是AutoCloseable.close()
方法:你只需在那里撤消替换:
public void close() throws Exception {
System.setOut(this.out);
}
最后,您需要一种方法来检索内容:
public String getContent() {
return this.stream.toString();
}
完成后,只需将CaptureOutput
传递给try
子句即可。下面的代码,例如......
public static void main(String[] args) throws Exception {
String content = null;
System.out.println("This will be printed");
try (CaptureOutput co = new CaptureOutput()) {
System.out.println("EXAMPLE");
content = co.getContent();
}
System.out.println("This will be printed, too.");
System.out.println("The content of the string is " + content);
}
...将导致此结果:
This will be printed
This will be printed, too.
The content of the string is EXAMPLE
请注意,我们不会在最后一行调用co.getContent()
。这是不可能的,因为与Python不同,co
变量的范围是try
子句。一旦try
块完成,它就会消失。[1]这就是我们从区块内获取价值的原因。
不那么优雅,对吗?解决方案可能是将BAOS提供给CaptureOutput
构造函数:
public CaptureOutput(ByteArrayOutputStream stream) {
this.stream = stream;
this.out = System.out;
System.setOut(new PrintStream(this.stream));
}
现在,我们稍后再使用该流:
public static void main(String[] args) throws Exception {
System.out.println("This will be printed");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try (CaptureOutput co = new CaptureOutput(stream)) {
System.out.println("EXAMPLE");
}
System.out.println("This will be printed, too.");
System.out.println("The content of the string is " + stream.toString());
}
(另外,无法在CaptureOutput
之前创建try
变量。这是有道理的:AutoCloseable
对象应该是"关闭"之后他们的使用。毕竟,使用封闭文件是什么?我们的用例与此有点不同,所以我们必须依赖其他选择。)
以下是完整的课程:
CaptureOutput.java
:
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class CaptureOutput implements AutoCloseable {
private ByteArrayOutputStream stream;
private PrintStream out;
public CaptureOutput(ByteArrayOutputStream stream) {
this.stream = stream;
this.out = System.out;
System.setOut(new PrintStream(this.stream));
}
public CaptureOutput() {
this(new ByteArrayOutputStream());
}
@Override
public void close() throws Exception {
System.setOut(this.out);
}
public String getContent() {
return this.stream.toString();
}
}
Main.java
:
import java.io.ByteArrayOutputStream;
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("This will be printed");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try (CaptureOutput co = new CaptureOutput(stream)) {
System.out.println("EXAMPLE");
}
System.out.println("This will be printed, too.");
System.out.println("The content of the string is " + stream.toString());
}
}