저는 변경할 수없는 Path 클래스가 있습니다. Test라는 또 다른 클래스에서는 Path 객체에 대한 마지막 참조가 있습니다.Java에서의 최종 가변 변수 변경
그러나 생성자와 getter 메서드 사이에 Path 객체는 변경 가능하지 않고 참조가 final 임에도 불구하고 변경됩니다. Path의 int 배열 노드 길이가 생성자에서 getter로 변경되기 때문에이 사실을 알고 있습니다. 그것은 대상이 완전하게 다른 것 인 것처럼 보인다.
내 프로그램은 멀티 스레드이지만 단일 스레드로 시도했지만 문제가 해결되지 않았습니다. 여기
는 불변의 경로 클래스public class Path implements Iterable<Point> {
private final int[] nodes;
private final double distance;
public Path(Scenario scenario, int gateway, int sensor){
this.scenario = scenario;
nodes = new int[2];
nodes[1] = -gateway - 1;
nodes[0] = sensor;
distance = scenario.DISTANCE_GATEWAY_SENSOR[gateway][sensor];
}
public Path(Path base, int newSensor){
scenario = base.scenario;
//Copy the old path. These are rigid structures so that we do not need to deep copy
nodes = new int[base.nodes.length + 1];
for(int i = 0; i < base.nodes.length; i++)
nodes[i + 1] = base.nodes[i];
nodes[0] = newSensor;
distance = base.distance + scenario.DISTANCE_SENSOR_SENSOR[newSensor][nodes[1]];
}
public Path(Scenario scenario, int[] nodes, boolean isSensor, double distance){
this.scenario = scenario;
this.distance = distance;
this.nodes = Arrays.copyOf(nodes, nodes.length);
if(!isSensor)
for(int i = 0; i < this.nodes.length; i++)
this.nodes[i] = -this.nodes[i] -1;
}
@Override
public Iterator<Point> iterator() {
return new PointIterator();
}
public class PointIterator implements Iterator<Point>{
private int next = -1;
@Override
public boolean hasNext() {
return next + 1 < nodes.length;
}
@Override
public Point next() {
int p = nodes[++next];
if(p >= 0)
return scenario.SENSOR_LOCATION[p];
return scenario.CS_LOCATION[-p - 1];
}
@Override
public void remove() {
throw new IllegalAccessError("This method is not supported");
}
}
}
이며, 여기에 테스트 클래스는 객체를 허용
public class Test {
private final Path gatewayTour;
public Test(Scenario scenario, boolean[] chosenGateway){
distanceFitness = 0;
Point current = scenario.SINK_LOCATION;
boolean visited[] = new boolean[scenario.CONFIG.NUM_CS];
int nextGateway;
LinkedList<Integer> order = new LinkedList<>();
do {
double minimumDistance = Double.MAX_VALUE;
nextGateway = -1;
for(int i = 0; i < scenario.CONFIG.NUM_CS; i++)
if(!visited[i] && CHOSEN_GATEWAYS[i] && scenario.CS_LOCATION[i].isCloserThan(minimumDistance, current)) {
nextGateway = i;
minimumDistance = scenario.CS_LOCATION[i].distance(current);
}
if(nextGateway >= 0) {
distanceFitness += minimumDistance;
visited[nextGateway] = true;
order.add(nextGateway);
current = scenario.CS_LOCATION[nextGateway];
}
} while(nextGateway >= 0);
int path[] = new int[order.size()];
Iterator<Integer> it = order.iterator();
for(int i = 0; i < order.size(); i++)
path[i] = it.next().intValue();
gatewayTour = new Path(scenario, path, false, distanceFitness);
}
public Path getGatewayTour(){
//Here, the gatewayTour object has changed and does not have the same content as in the constructor
return gatewayTour;
}
}
내 프로그램 있나요 (경로 클래스에 대한 최종 참조)입니다 바꾸다? 나는 더 정확해질 것이다 : woud가 Path 클래스의 int 배열 "노드"가 길이를 바꿀 수 있도록 허용 할 것인가? 이것이 실제 문제이기 때문입니다.
[편집] : 내 테스트에 결함이있어 내 노드 배열의 가치가 바뀌 었다고 믿었습니다. 내 코드의 결함이나 가능한 개선 사항을 지적한 모든 사람들에게 감사드립니다.
AlexR의 대답은 최종 배열에서 개별 요소를 변경할 수 있다고 지적했기 때문에 받아 들일 것입니다. 내가 모르는 어떤 것이 문제를 해결하는 데 도움이됩니다.
'// 변수를 초기화하기 위해 여기에 일부 생성자를 표시 하시겠습니까?' – fge
BTW,'.remove()'는'UnsupportedOperationException'을 throw해야합니다. – fge
최종 컨테이너의 내용을 변경할 수는 있지만 참조 해제하거나 다시 참조 할 수는 없습니다. 생성자와 getter를 볼 수 있습니까? – arynaq