익명 클래스에 매개 변수를 전달하려면 어떻게 해야 합니까?
파라미터를 전달하거나 익명의 클래스에 외부 파라미터에 액세스할 수 있습니까?예를 들어 다음과 같습니다.
int myVariable = 1;
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// How would one access myVariable here?
}
});
리스너를 실제 이름 있는 클래스로 만들지 않고 리스너가 myVariable에 액세스하거나 myVariable을 전달할 수 있는 방법이 있습니까?
네, 'this'를 반환하는 이니셜라이저 메서드를 추가하고 즉시 해당 메서드를 호출합니다.
int myVariable = 1;
myButton.addActionListener(new ActionListener() {
private int anonVar;
public void actionPerformed(ActionEvent e) {
// How would one access myVariable here?
// It's now here:
System.out.println("Initialized with value: " + anonVar);
}
private ActionListener init(int var){
anonVar = var;
return this;
}
}.init(myVariable) );
'최종' 선언은 필요 없습니다.
엄밀히 말하면, 익명의 수업에는 컨스트럭터가 있을 수 없기 때문입니다.
그러나 클래스는 범위를 포함하는 변수를 참조할 수 있습니다.어나니머스 클래스의 경우 포함된 클래스의 인스턴스 변수 또는 최종으로 표시된 로컬 변수일 수 있습니다.
edit: Peter가 지적한 바와 같이 익명 클래스의 슈퍼 클래스 작성자에게 파라미터를 전달할 수도 있습니다.
네. 내부 클래스에서 볼 수 있는 변수를 캡처할 수 있습니다.유일한 제한은 그것이 최종이어야 한다는 것이다.
다음과 같이 합니다.
final int myVariable = 1;
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Now you can access it alright.
}
});
이거면 마법이 될 거야
int myVariable = 1;
myButton.addActionListener(new ActionListener() {
int myVariable;
public void actionPerformed(ActionEvent e) {
// myVariable ...
}
public ActionListener setParams(int myVariable) {
this.myVariable = myVariable;
return this;
}
}.setParams(myVariable));
http://www.coderanch.com/t/567294/java/java/declare-constructor-anonymous-class 에 나타나듯이 인스턴스 이니셜라이저를 추가할 수 있습니다.이름이 없고 (컨스트럭터처럼) 먼저 실행되는 블록입니다.
Java 인스턴스 이니셜라이저에서도 논의되는 것 같습니다.인스턴스 이니셜라이저는 컨스트럭터와 어떻게 다른가요?그럼 컨스트럭터와의 차이점에 대해 설명합니다.
이 솔루션은 구현된 익명 클래스를 반환하는 메서드를 사용하는 것입니다.정규 인수는 메서드에 전달될 수 있으며 익명 클래스 내에서 사용할 수 있습니다.
예: (일부 GWT 코드에서 텍스트 상자 변경을 처리합니다.)
/* Regular method. Returns the required interface/abstract/class
Arguments are defined as final */
private ChangeHandler newNameChangeHandler(final String axisId, final Logger logger) {
// Return a new anonymous class
return new ChangeHandler() {
public void onChange(ChangeEvent event) {
// Access method scope variables
logger.fine(axisId)
}
};
}
이 예에서는 새로운 어나니머스 class-method가 다음과 같이 참조됩니다.
textBox.addChangeHandler(newNameChangeHandler(myAxisName, myLogger))
또는 OP의 요건을 사용하여 다음을 수행합니다.
private ActionListener newActionListener(final int aVariable) {
return new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Your variable is: " + aVariable);
}
};
}
...
int myVariable = 1;
newActionListener(myVariable);
다른 사람들은 이미 익명 클래스가 최종 변수에만 액세스할 수 있다고 대답했습니다.그러나 그들은 원래의 변수를 어떻게 최종값이 아닌 상태로 유지할 것인가 하는 문제를 열어두고 있다.Adam Mlodzinski는 해결책을 제시했지만 꽤 비대하다.이 문제에 대한 훨씬 더 간단한 해결책이 있습니다.
당신이 원하지 않는다면myVariable
최종적으로는 새로운 범위로 묶어야 합니다.최종인지 아닌지는 중요하지 않습니다.
int myVariable = 1;
{
final int anonVar = myVariable;
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// How would one access myVariable here?
// Use anonVar instead of myVariable
}
});
}
Adam Mlodzinski는 그의 대답에서 다른 어떤 것도 하지 않고 훨씬 더 많은 코드를 가지고 있다.
플레인 람다("lambda 식은 변수를 캡처할 수 있습니다")를 사용할 수 있습니다.
int myVariable = 1;
ActionListener al = ae->System.out.println(myVariable);
myButton.addActionListener( al );
또는 기능까지
Function<Integer,ActionListener> printInt =
intvar -> ae -> System.out.println(intvar);
int myVariable = 1;
myButton.addActionListener( printInt.apply(myVariable) );
함수를 사용하면 데코레이터와 어댑터를 리팩터링할 수 있습니다.여기를 참조해 주십시오.
람다에 대해 배우기 시작한 지 얼마 안 됐으니, 혹시라도 실수를 발견하면 댓글을 달아주세요.
외부 변수에 값을 넣는 간단한 방법(익명 클래스에 속하지 않음)은 다음과 같습니다.
마찬가지로 외부 변수 값을 가져오려면 원하는 값을 반환하는 메서드를 만들 수 있습니다.
public class Example{
private TypeParameter parameter;
private void setMethod(TypeParameter parameter){
this.parameter = parameter;
}
//...
//into the anonymus class
new AnonymusClass(){
final TypeParameter parameterFinal = something;
//you can call setMethod(TypeParameter parameter) here and pass the
//parameterFinal
setMethod(parameterFinal);
//now the variable out the class anonymus has the value of
//of parameterFinal
});
}
"myVariable"이 필드인 경우 다음과 같이 수식할 수 있습니다.
public class Foo {
int myVariable = 1;
new ActionListener() {
public void actionPerformed(ActionEvent e) {
Foo.this.myVariable = 8;
}
});
}
익명의 수업은 기본적으로 람다와 같다고 생각했는데 더 나쁜 구문으로는...이는 사실이지만 구문은 더욱 악화되어 로컬 변수가 포함된 클래스로 블리딩됩니다.
부모 클래스의 필드로 만들어 최종 변수에 액세스할 수 없습니다.
예
인터페이스:
public interface TextProcessor
{
public String Process(String text);
}
클래스:
private String _key;
public String toJson()
{
TextProcessor textProcessor = new TextProcessor() {
@Override
public String Process(String text)
{
return _key + ":" + text;
}
};
JSONTypeProcessor typeProcessor = new JSONTypeProcessor(textProcessor);
foreach(String key : keys)
{
_key = key;
typeProcessor.doStuffThatUsesLambda();
}
Java 8(EE world에 갇혀 있고 아직 8이 되지 않음)에서 이 문제를 해결했는지 모르겠지만 C#에서는 다음과 같습니다.
public string ToJson()
{
string key = null;
var typeProcessor = new JSONTypeProcessor(text => key + ":" + text);
foreach (var theKey in keys)
{
key = theKey;
typeProcessor.doStuffThatUsesLambda();
}
}
c#에는 별도의 인터페이스가 필요 없습니다.그립다!자바에서 더 나쁜 디자인을 만들고 더 많은 것을 반복하고 있습니다. 왜냐하면 어떤 것을 재사용하기 위해 자바에서 추가해야 하는 코드와 복잡성의 양은 복사하여 붙여넣는 것보다 더 나쁘기 때문입니다.
언급URL : https://stackoverflow.com/questions/5107158/how-to-pass-parameters-to-anonymous-class
'programing' 카테고리의 다른 글
C에서는 어레이가 포인터입니까, 포인터로 사용됩니까? (0) | 2022.06.07 |
---|---|
Vue.js Vuex 스토어를 올바르게 사용하는 방법watch() 메서드가 맞습니까? (0) | 2022.06.07 |
Vue에서 정적 구성 요소를 동적 구성 요소에 추가하는 방법 (0) | 2022.06.07 |
malloc은 얼라인먼트를 어떻게 이해하나요? (0) | 2022.06.07 |
C의 시프트 연산자를 사용한 곱셈과 나눗셈이 실제로 더 빠릅니까? (0) | 2022.06.06 |