内部类访问外部类的变量必须是final吗?

如下:

package com.java.concurrent;

class A {
int i = 3; public void shout() { class B {
public void shout1() {
System.out.println(i);
} }
B b = new B();
b.shout1();
} public static void main(String[] args) {
A a = new A();
a.shout();
}
}

可正常输出3,证明可以访问类的变量i,但改为下面的方式:

class A {
public void shout(int temp) {
final int i = temp;
class B {
public void shout1() {
System.out.println(i);
} }
B b = new B();
b.shout1();
} public static void main(String[] args) {
A a = new A();
a.shout(3);
}
}
此时i必须为final,怎么理解呢?收起

 

 

最佳答案

 
  是的,因为生命周期的原因。方法中的局部变量,方法结束后这个变量就要释放掉,final保证这个变量始终指向一个对象。

  首先,内部类和外部类其实是处于同一个级别,内部类不会因为定义在方法中就会随着方法的执行完毕而跟随者被销毁。问题就来了,
  如果外部类的方法中的变量不定义final,那么当外部类方法执行完毕的时候,这个局部变量肯定也就被GC了,然而内部类的某个方法还没有执行完,
  这个时候他所引用的外部变量已经找不到了。如果定义为final,java会将这个变量复制一份作为成员变量内置于内部类中,
  这样的话,由于final所修饰的值始终无法改变,所以这个变量所指向的内存区域就不会变。
java静态方法中不能引用非静态变量
因为我们知道静态的方法可以在没有创建实例时使用,而申明为非静态的成员变量是一个对象属性,它只有在对象存在时引用,因此如果在对象未创建实例时我们在静态方法中调用了非静态成员方法自然是非法的,所以编译器会在这种时候给各错误.

简单说来,静态方法可以不用创建对象就调用,非静态方法必须有了对象的实例才能调用.因此想在静态方法中引用非静态方法是不可能的,因为它究竟引用的是哪个对象的非静态方法呢?编译器不可能给出答案,因为没有对象啊,所以要报错

class HelloWorld


int a1 = 6;

public static void main(String[] args) 

  
   System.out.print(a1);    
/**   成员变量不能直接调用  ( 无法从静态上下文中引用非静态变量   a1  )             
   */ 

}

静态方法中不能创建内部类的实例

如上图所示,Outter是一个普通的类,Inner是Outter类里面的内,属于内部类。在main方法中试图创建Inner的实例,Eclipse会有报错提示,大意是:“没有Outter可以访问的实例,必须指定一个Outter类的实例(如:x.new A() 其中x就是一个Outter类的实例)”

原因:

内部类的特点是可以访问外部类的成员变量,而成员变量只能在创建了实例之后才能访问。

那么main方法是个静态方法,即可以不创建Outter的实例就能访问这个方法,这时候如果Inner可以创建实例,那么inner的实例就有可能访问Outter对象的成员变量。

但main方法是静态方法可以不创建对象就运行,Outter对象都没有创建,Inner就算能创建对象,也有可能访问不到Outter对象的成员变量。

所以,是不能在静态方法中创建内部类的对象,防止该内部类对象在外部类对象创建前访问外部类的成员变量。

内部类访问外部类的变量必须是final吗,java静态方法中不能引用非静态变量,静态方法中不能创建内部类的实例的更多相关文章

  1. “全栈2019”Java第六十九章:内部类访问外部类成员详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  2. ERROR无法从静态上下文中引用非静态变量

    ERROR无法从静态上下文中引用非静态变量 2012-06-16 20:58:52 分类: Java 什么是“static”? 学习过java.C++或C的人都应该认识这个关键字.用这个关键字修饰的变 ...

  3. C++中内部类访问外部类的私有成员

    首先,如果不知道什么是内部类InnerClass的话,就没必要往下看了. 尝试在C++中模仿apple objective-c 的Grand Dispatch简化多线程编程时,使用了boost::fu ...

  4. 内部类访问外部类成员变量,使用外部类名.this.成员变量

    public class Outer { private int age = 12; class Inner { private int age = 13; public void print() { ...

  5. 学以致用,通过字节码理解:Java的内部类与外部类之私有域访问

    目录: 内部类的定义及用处 打开字节码理解内部类 一.内部类的定义及用处 内部类(inner class)是定义在另一个类中的类.使用内部类,我们可以: 访问该类定义所在的作用域中的数据,包括私有的数 ...

  6. Java内部类和外部类的通信探索

    1.内部类访问外部类的成员和方法 在内部类中,可以无障碍地访问外部类的所有成员和方法. 在下面的实验代码中,可以看到,内部类sl可以访问外部类的私有成员:sz 和 cur. 同时可以访问私有方法:pr ...

  7. Java嵌套类,内部类和外部类

    1.嵌套类,内部类 嵌套类是指被定义在一个类内部的类: JAVA的嵌套类有很多种类:1.静态成员类:2.非静态成员类:3.匿名类:4.局部类:其中,除了静态成员类之外,其他的都是内部类,因为静态成员类 ...

  8. java学习(四)static静态变量 和this

    java中的this /* this:是当前类的对象引用.简单的记,它就代表当前类的一个对象. 注意:谁调用这个方法,在该方法内部的this就代表谁. this的场景: 解决局部变量隐藏成员变量 */ ...

  9. "静态方法里仅仅能调用静态变量和静态方法"具体解释

    静态方法里能够调用静态方法和静态变量,同一时候也能调用非静态方法和非静态变量. public class Test { public Test() {}; public Test(int i) {th ...

随机推荐

  1. HTML 学习笔记(链接)

    HTML链接 超链接可以是一个字,一个词,或者一组词,也可以是一幅图像,您可以点击这些内容来跳转到新的文档或者当前文档中的某个部分. 当您把鼠标指针移动到网页中的某个链接上时,箭头会变为一只小手. 我 ...

  2. jquery noConflict详解

    noConflict是防止其他库也用了$作为全局变量而引起的冲突,我们看看jquery是怎么做的 首先jquery在代码的开始部分定义了2个私有变量: _jQuery = window.jQuery ...

  3. webpack webpack-dev-server使用指南

    webpack-dev-server插件可以实现webpack的自动编译刷新 项目结构 pockage.js { "name": "webpack", &quo ...

  4. AngularJs 时间格式化处理

    1.AngularJs的controller中格式: var dateAsString = $filter('date')(item_date, "yyyy-MM-dd hh:mm:ss&q ...

  5. Anyconnect的VPN环境部署(1)-OpenConnect server(ocserv)服务安装

    打算在公司IDC机房部署一套VPN环境,经过考虑,最终决定采用Cisco下的开源技术AnyConnect.AnyConnect的优势有:1)长连接,待机不会断开:2)速度快,稳定性好:3)安全性好,全 ...

  6. STL标准库面试常考知识点

    C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作.vecto ...

  7. 用Myisamchk让MySQL数据表更健康

    用Myisamchk让MySQL数据表更健康 2011-03-15 09:15 水太深 ITPUB 字号:T | T 为了让MySQL数据库中的数据表“更健康”,就需要对其进行定期体检.在这里笔者推荐 ...

  8. Codevs1026 逃跑的拉尔夫

    题目描述 Description 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的移动 ...

  9. Java 基础命名空间

    java.lang (提供利用 Java 编程语言进行程序设计的基础类)java.lang.annotation(提供了引用对象类,支持在某种程度上与垃圾回收器之间的交互)java.lang.inst ...

  10. Linux 网络编程详解十

    select int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *tim ...