- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Android 项目中,我使用下面的代码。我收到错误消息:variable tts might not have been initialized
。如果我更改声明变量 tts 的位置,我将不再收到错误。如果我在内部 OnInitListener 类中注释掉引用 tts 的两行,我也不再收到错误(但也没有任何有趣的事情发生)。
因此,我推断如果在封闭方法中声明了 tts
变量(即使它被声明为 final
),内部类也无法“看到”它,但是当它被声明为封闭类的实例变量时它可以看到它。
我有 JavaScript 背景;显然,Java 在此上下文中以不同的方式处理变量范围。如果您能解释一下 Java 在幕后做了什么,我将不胜感激,这样我就能理解这些差异。
package com.example.texttospeech;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import java.util.HashMap;
import java.util.Locale;
public class MainActivity extends ActionBarActivity {
//private TextToSpeech tts; // UNCOMMENT THIS...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testTextToSpeech();
}
private void testTextToSpeech() {
final String toSpeak = getString(R.string.hello_world);
final int mode = TextToSpeech.QUEUE_FLUSH;
final HashMap hashMap = new HashMap<String, String>();
final TextToSpeech tts; // ... AND COMMENT THIS OUT...
tts = new TextToSpeech(getApplicationContext(),
new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR) {
// ... OR SIMPLY COMMENT OUT THE NEXT TWO LINES
tts.setLanguage(Locale.UK);
tts.speak(toSpeak, mode, hashMap);
}
}
});
}
}
最佳答案
-#1 方法中的所有最终变量都被隐式复制为 onInitClass 的字段。它还对您的外部类有一个隐式字段。所有这些都可能是意外内存泄漏的来源,我们所说的泄漏是指意外创建一个引用,阻止垃圾收集器完成其工作,因此在声明 final 时需要小心。
-#2 它说 tts 可能没有被初始化的原因是因为你在给它赋值之前使用它。 Final 使引用不可变,因此您只能在声明时为 final 赋值。如果您不分配值,则意味着占用内存空间的很可能是上次使用内存空间存储值时的随机垃圾。您可以显式设置 tts = null,但是将 final 变量设置为 null 是完全无用的(它无法更改),因此您需要在声明它的同一行中设置它的实际值。
例如final TextToSpeech tts = new TextToSpeech(getApplicationContext(), listener);
-#3 你的内部类可以引用外部类中的变量。你所做的就是编写 OuterClass.this.myfield;
因此,这可能是一种重写代码的可行方法。
TextToSpeech tts; //class field
private void testTextToSpeech() {
final String toSpeak = getString(R.string.hello_world);
final int mode = TextToSpeech.QUEUE_FLUSH;
final HashMap<String, String> hashMap = new HashMap<String, String>();
tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR) {
tts.setLanguage(Locale.UK);
tts.speak(toSpeak, mode, hashMap);
}
}
});
}
关于java - 了解 Java 内部类中的作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26821773/
我是一名优秀的程序员,十分优秀!