如何使用JUnit来测试某些代码是否抛出异常?

我当然可以这样做:

@Test
public void testFooThrowsIndexOutOfBoundsException() {
  boolean thrown = false;

  try {
    foo.doStuff();
  } catch (IndexOutOfBoundsException e) {
    thrown = true;
  }

  assertTrue(thrown);
}

我记得,对于这类情况,有一个注释或Assert.xyz之类的东西远没有JUnit那么笨拙,更符合JUnit的精神。

如何使用sed删除文本文件中包含特定字符串的所有行?

让我先说一下,我知道foreach是什么、做什么以及如何使用它。这个问题涉及到它在引擎盖下的工作方式,我不希望有任何类似于“这是如何使用foreach循环数组”的答案。


在很长一段时间里,我假设foreach使用数组本身。然后,我发现了许多关于它与数组副本一起工作的事实的引用,因此我认为这就是故事的结尾。但我最近就此事进行了一次讨论,经过一点实验后发现,事实上这并非100%正确。

让我表明我的意思。对于以下测试用例,我们将使用以下阵列:

$array = array(1, 2, 3, 4, 5);

测试用例1:

foreach ($array as $item) {
  echo "$item\n";
  $array[] = $item;
}
print_r($array);

/* Output in loop:    1 2 3 4 5
   $array after loop: 1 2 3 4 5 1 2 3 4 5 */

这清楚地表明,我们没有直接使用源数组,否则循环将永远继续,因为我们在循环期间不断将项推到数组上。但为了确保情况是这样的:

测试用例2:

foreach ($array as $key => $item) {
  $array[$key + 1] = $item + 2;
  echo "$item\n";
}

print_r($array);

/* Output in loop:    1 2 3 4 5
   $array after loop: 1 3 4 5 6 7 */

这支持了我们最初的结论,我们在循环期间使用源数组的副本,否则我们将在循环期间看到修改的值。但是

如果我们查看手册,我们会发现以下陈述:

当foreach第一次开始执行时,内部数组指针将自动重置为数组的第一个元素。

正确的这似乎表明foreach依赖于源数组的数组指针。但我们已经证明我们没有使用源阵列,对吗?嗯,不完全是。

测试用例3:

// Move the array pointer on one to make sure it doesn't affect the loop
var_dump(each($array));

foreach ($array as $item) {
  echo "$item\n";
}

var_dump(each($array));

/* Output
  array(4) {
    [1]=>
    int(1)
    ["value"]=>
    int(1)
    [0]=>
    int(0)
    ["key"]=>
    int(0)
  }
  1
  2
  3
  4
  5
  bool(false)
*/

因此,尽管我们不是直接使用源数组,但我们是直接使用源阵列指针-指针位于循环末尾的数组末尾这一事实表明了这一点。但这不可能是真的——如果是,那么测试用例1将永远循环。

PHP手册还指出:

由于foreach依赖于内部数组指针,因此在循环中更改它可能会导致意外行为。

好吧,让我们来看看“意外行为”是什么(从技术上讲,任何行为都是意外的,因为我不再知道会发生什么)。

测试用例4:

foreach ($array as $key => $item) {
  echo "$item\n";
  each($array);
}

/* Output: 1 2 3 4 5 */

测试用例5:

foreach ($array as $key => $item) {
  echo "$item\n";
  reset($array);
}

/* Output: 1 2 3 4 5 */

……没有什么出乎意料的,事实上,它似乎支持“复制源”理论。


问题

这是怎么回事?我的C-fu不够好,我无法通过查看PHP源代码得出正确的结论,如果有人能为我将其翻译成英语,我将不胜感激。

在我看来,foreach使用数组的副本,但在循环后将源数组的数组指针设置到数组的末尾。

这是正确的吗?如果没有,它到底在做什么?在foreach期间使用调整数组指针的函数(each()、reset()等)是否会影响循环的结果?

我想选择具有两个类a和b的所有元素。

<element class="a b">

因此,只有同时具有这两个类的元素。

当我使用$(“.a,.b”)时,它给了我并集,但我想要交集。

从我在Java中使用线程的时间来看,我发现了两种编写线程的方法:

使用可运行的机具:

public class MyRunnable implements Runnable {
    public void run() {
        //Code
    }
}
//Started with a "new Thread(new MyRunnable()).start()" call

或者,使用扩展线程:

public class MyThread extends Thread {
    public MyThread() {
        super("MyThread");
    }
    public void run() {
        //Code
    }
}
//Started with a "new MyThread().start()" call

这两个代码块有什么显著的区别吗?

我想做一些事情,比如:

MyObject myObj = GetMyObj(); // Create and fill a new object
MyObject newObj = myObj.Clone();

然后对未反映在原始对象中的新对象进行更改。

我通常不需要这个功能,所以当有必要时,我会创建一个新对象,然后单独复制每个属性,但这总是让我觉得有更好或更优雅的方法来处理这种情况。

如何克隆或深度复制对象,以便在原始对象中不反映任何更改的情况下修改克隆的对象?

我试图在一个新的选项卡中打开一个URL,而不是弹出窗口。

我见过一些相关的问题,其中的回答大致如下:

window.open(url,'_blank');
window.open(url);

但没有一个对我有效,浏览器仍然试图打开一个弹出窗口。

假设我在Git存储库中。我删除一个文件并提交更改。我继续工作,并做出更多承诺。然后,我发现删除该文件后需要恢复该文件。

我知道我可以使用gitcheckout<commit>--filename.txt签出文件,但我不知道该文件何时被删除。

如何查找删除给定文件名的提交?如何将该文件恢复到工作副本中?