我已经通过this question on legality of forward references ,但不清楚Java语言中forward references
的含义。有人可以借助一个例子来解释吗?
答案 0 :(得分:14)
这特别是编译错误。它的全部都是关于类变量声明的排序。我们将一些代码用于说明目的:
public class ForwardReference {
public ForwardReference() {
super();
}
public ForwardReference echoReference() {
return this;
}
public void testLegalForwardReference() {
// Illustration: Legal
this.x = 5;
}
private int x = 0;
// Illustration: Illegal
private ForwardReference b = a.reference();
private ForwardReference a = new ForwardReference();
}
正如您所看到的,Java允许您在类方法中引用类变量,即使变量的声明在之后 >方法。这是(合法)前向引用的示例,对此的支持内置于Java编译器中。
你 不能 做的是声明一个类变量'a',它取决于尚未声明的另一个类变量'b'。依赖类变量声明必须以它们的依赖性的相反顺序出现。
在切线上,如果您的代码包含非法引用错误,大多数(如果不是全部)IDE都会发出警告。
JLS的section 8.3.2.3涵盖了非法的正向引用。
答案 1 :(得分:3)
如果你有
,它基本上只是编译器读取内容的顺序int c = 3
int a = b;
int b = 5;
编译器将从上到下读取它,因此它将是第一行,它声明一个变量'c',并将其赋值为3,这很好,然后它将遇到第二行,它声明变量'a',然后尝试将其分配给'b'。
但是现在,编译器有一个问题:这个'b'是什么东西?它还只学习了'c',而且最近才知道'a',但是它没有任何关于'b'的知识,因为对于编译器来说,它还没有被声明。那么,既然编译器无法处理所有的混淆,它就会停止,并让你知道你做了什么来激怒它。
因此,前向参考部分将是对尚不存在的东西的引用。及时前进..
答案 2 :(得分:1)
简单来说,它意味着在代码文件中进一步向下引用(访问变量,调用函数)。
static int x=getY();
static int y=5;
static int getY() { return y; }
答案 3 :(得分:1)
import random
import tkinter as tk
root = tk.Tk()
user_input = tk.Entry(root)
user_input.pack()
greetings = ['hola', 'hello', 'hi', 'Hi', 'hey!', 'hey']
question = ['How are you?', 'How are you doing?']
responses = ['Okay', "I'm fine"]
huh = "I did not understand what you said"
def cb():
user_text = user_input.get()
if user_text in greetings:
bot_text = random.choice(greetings)
elif user_text in question:
bot_text = random.choice(responses)
else:
bot_text = huh
output.config(text=bot_text)
button = tk.Button(root, text="Enter", command=cb)
button.pack()
output = tk.Label(root, text='')
output.pack()
tk.mainloop()
*********参考案例 - 1 *********
不允许使用前向引用实例变量,因为编译器不确定我们正在引用的值的类型,或者甚至可能没有这样的变量。
考虑一个例子: -
import random
import tkinter as tk
root = tk.Tk()
user_input = tk.Entry(root)
user_input.pack()
greetings = ['hola', 'hello', 'hi', 'Hi', 'hey!', 'hey']
question = ['How are you?', 'How are you doing?']
responses = ['Okay', "I'm fine"]
huh = "I did not understand what you said"
def cb(event):
user_text = user_input.get()
if user_text in greetings:
bot_text = random.choice(greetings)
elif user_text in question:
bot_text = random.choice(responses)
else:
bot_text = huh
output.config(text=bot_text)
user_input.bind("<Return>", cb)
output = tk.Label(root, text='')
output.pack()
tk.mainloop()
如果在上述情况下允许前向引用,那么它可能会造成严重破坏。
public class AnyCode {
void print() {
System.out.println("Value of j - " + j); // legal
System.out.println("Value of i - " + i); // legal
}
// CASE - 1
int k = i; // illegal
int i;
// CASE - 2
int l = j; // legal
static int m = j; // illegal
static int j;
// CASE - 3
A aObj = bObj; // illegal
B bObj = new B();
public static void main(String[] args) {
/*
Note :- here anyCode act as a local variable and get space on stack
whereas the object it is referring to is present on heap. And you
cannot forward reference a local variable.
*/
anyCode.print(); // 'Cannot find symbol' error
AnyCode anyCode = new AnyCode();
}
}
class A {
}
class B {
}
在上面的例子中我决定不宣布b,现在如果java允许这样的赋值,那么它将是一场噩梦。
**********请参阅案例 - 2 *********
静态变量在实例变量之前加载,因此转发引用静态变量并将它们分配给实例变量是完全正确的