Java: Why does this method have side effects?

final, java, jgrapht, side-effects, testcase

Solution

The `final` modifier only means that the reference cannot be reassigned. It does not prevent the object's state from being modified.

EDIT: Just for Tom:

public void doSomething1(Object arg)
{
    arg = new Object(); // OK.
}

public void doSomething2(final Object arg)
{
    arg = new Object(); // Compile error.
}

In both cases you can invoke methods on the object pointed to by `arg`, including methods that modify its state.

Problem

I have a method that is producing side effects, even though certain variables are marked `final`. Why is this? Perhaps I am confused about what `final` does. ``` @Test public void testSubGraph() { WeightedGraph<String, DefaultWeightedEdge> g = generateSimpleCaseGraph(); Graph<String, DefaultWeightedEdge> sub = ChooseRoot.subgraphInDirection(g, "alpha", "l"); assertEquals(g, generateSimpleCaseGraph()); //fails } public static <V, E extends DefaultEdge> Graph<V, E> subgraphInDirection(final Graph<V, E> g, final V start, final V sink) { Graph<V, E> sub = removeEdges(g, start, sink); return removeUnconnectedNodes(sub, start); } private static <Vertex, Edge extends DefaultEdge> Graph<Vertex, Edge> removeEdges(final Graph<Vertex, Edge> g, Vertex start, Vertex sink) { final Set<Edge> outEdges = new HashSet<Edge>(g.edgesOf(start)); boolean removedEdge; for (Edge e : outEdges) { if (! (g.getEdgeTarget(e).equals(sink) || g.getEdgeSource(e).equals(sink))) { removedEdge = g.removeEdge(e); assert removedEdge; } } return g; } private static <Vertex, Edge> Graph<Vertex, Edge> removeUnconnectedNodes(Graph<Vertex, Edge> g, Vertex start) { ConnectivityInspector<Vertex, Edge> conn = new ConnectivityInspector<Vertex, Edge>((UndirectedGraph<Vertex, Edge>) g); boolean removedVertex; final Set<Vertex> nodes = new HashSet<Vertex>(g.vertexSet()); for (Vertex v : nodes) { if (! conn.pathExists(start, v)) { removedVertex = g.removeVertex(v); assert removedVertex; } } return g; } ```

Original source