目的

  为什么会有这篇文章呢,是因为我在学习各种框架的时候发现很多框架都用到了这些内部类的小技巧,虽然我平时写代码的时候基本不用,但是看别人代码的话至少要了解基本知识吧,另外到底内部类应该应用在哪些场合,我并不是很清楚,留下一些值得思考的问题作为记录,说不定以后能自己来填。于是就会有这篇文章啦。

  常规使用方法我也不想介绍,网上一大把,我就说说比较容易错的,值得注意的地方。

注意

  这篇文章只是分享一下我对内部类的一些研究与困惑吧,说不定对大家有帮助,说不定能引导大家一起思考学习。Java语法知识其实是很复杂很容易错的,特别是在细节方面。所以我的观点可能会有各种错误。

  另外我的JDK版本是1.7。JDK1.8的版本貌似对内部类的规则有一些修改,所以请大家注意。

非静态非匿名内部类

不能拥有static成员

网上大部分文章的说法大致是这样的,就是告诉你这种内部类不能拥有static的方法,属性。其实这句话有那么点小问题。非静态内部类也可以拥有static的属性的(static区块不行),但是要求这个static属性必须是常量,这个地方经过我的研究,我觉得和 “调用类的static属性,但却不会初始化这个类的static区块和其他static变量” 有点相似。什么意思?就是说

 class Outter{
class Inner{
final static int a = 9;
}
}

这样是没有编译错误的。要求静态变量a必须是final类型的,且是基本类型,且是字面值

 class Outter{
class Inner{
final static int a = get();
} static int get(){
return 1;
}
}

这样就会报错,因为a不是字面值。

这里我想请大家看一下我的另外一篇学习记录,这种变量是不会触发类初始化的。

地址:http://www.cnblogs.com/abcwt112/p/4567332.html 分析标题下面的第二小点。

当然,这种字面值貌似没什么卵用啊。。。。所以说这种内部类不能有static成员大致上好像也算对吧。。

为什么不能拥有static成员?

我觉得道理是这样的(个人理解)。非静态的内部类是和普通成员一样的,是隶属于外部类对象的,创建这种内部类对象需要先创建外部类对象。也就是说这种内部类是不能单独于外部类对象存在的。这个道理大家都明白,一个成员变量怎么能脱离于类的对象独立存在呢。那假设这种内部类可以拥有static的属性,比如static int a = 1;那这个a数据存在哪里呢?根据前面的分析,应该是存在于分配给外部类对象拥有的内存中的,那么等外部类对象呗销毁以后,这个a分配的内存也会被销毁。这样的话修改这个a毫无意义,因为每次都是重新分配内存,每次值都是1。所以这个static没什么用,并不是全局的。

这个问题我是这么理解的。我觉得等我看完JVM虚拟机(我觉得有可能final static int与static int变量值存的地方可能不一样)或者学习汇编(可以观察数据是怎么存储的)以后再看它可能会有更深的理解。

静态内部类

只能调用外部类的静态方法与属性

这点蛮好理解,就像静态方法main里不能调用非静态的属性,方法一样。但是这并不代表静态内部类就不能定义 非静态的方法和属性。它不能调用外部类的非静态的成员,但是却可以在自己内部定义。毕竟它是个类。。。。

 public class StaticTest {
static int a = 9; private static class Inner{
public static void main(String[] args) {
System.out.println(StaticTest.a);
} public void doSomething(){ }
}
public static class Inner2{
}
}

这里代码就没有什么问题,能编译通过(doSomething方法)。

用途(废话)

  静态内部类是没有指向外部类的引用的,所以说它和外部类并没有什么关系,因此,即使没有外部类的对象,也可以直接创建静态内部类的对象。但是我觉得如果是这样使用的话,那完全没必要把类弄成静态内部的,直接创建外部类一般的类就OK了。所以说静态内部类肯定有它自己独特的作用。既然是个内部类,我觉得应该会声明成private,不然还不如创建一个外部类呢。。。。那private static的class有啥用处呢?我也不清楚。。。现在我唯一觉得有用的地方就是可以把测试代码main方法写在里面。因为是private的类,外接不能调用它,也就不能调用写的main函数了。。但是如果只是测试的话可以使用junit test呀。。。不可能为了测试就专门搞这么一个语法。。。这点值得日后研究,等我代码看得多了,说不定会有新体会。

  我看Apache Shiro框架中的Ini类就有个静态内部类Section(被声明为public类型),这个Section类独立存在毫无意义,外部只需要用到Ini类就行了。但是又不能没有,因为这个类地位其实和外部类Ini差不多,Ini是整个配置文件的抽象,Section是整个配置文件中每一小节的抽象。如果没有这个类,可能Ini中可能需要定义大量的static方法和大量的map来做关联,这样可能会很麻烦,所以shiro用到了这个静态内部类。具体内容可以查看我的另外一篇文章,介绍了Ini类:http://www.cnblogs.com/abcwt112/p/4641500.html

Java 静态内部类与非静态内部类 学习记录.的更多相关文章

  1. JAVA静态和非静态内部类

    JAVA静态和非静态内部类 一直对java的静态和非静态内部类的东东理解不清楚,今天测试了一下,下面把测试结果记录一下,加深印象.用于以后查找. 直接上代码. package com.test.xml ...

  2. 【java提高】(18)---静态内部类和非静态内部类

    java提高](18)-静态内部类和非静态内部类 定义 放在一个类的内部的类我们就叫内部类. 自己从开发到现在其实用到内部类主要在两个地方会考虑用内部类: 1.使用静态内部类的单例模式 2.将Json ...

  3. 《java入门第一季》之面向对象静态内部类和非静态内部类的区别

    很感谢在内部类章节,"开心阳"先生给与的建议.使用静态内部类.这里就简单说一下静态内部类的使用. package com.devin; public class MyMain{ p ...

  4. Java中static关键字声明的静态内部类与非静态内部类的区别

    (1)内部静态类不需要有指向外部类的引用.但非静态内部类需要持有对外部类的引用.(2)非静态内部类能够访问外部类的静态和非静态成员.静态类不能访问外部类的非静态成员.他只能访问外部类的静态成员.(3) ...

  5. java开源项目之IQQ学习记录之项目环境搭建与启动

    本文链接地址:http://blog.csdn.net/sushengmiyan/article/details/18779727 作者:sushengmiyan 现在就码字说说今天晚上搞定的一个项目 ...

  6. JAVA基础语法 我的学习记录

    1.标识符 Java所有的组成部分都需要名字.类名.变量名以及方法名都被称为标识符. 关于Java标识符,有以下几点需要注意: 所有的标识符都应该以字母(A-Z或者a-z),美元符($).或者下划线( ...

  7. 《Java程序设计》第二周学习记录(2)

    目录 3.1 运算符与表达式 3.3 if条件分支语句 3.7 for语句与数组 参考资料 3.1 运算符与表达式 和C语言基本上没有区别,要注意的是关系运算符的输出结果是bool型变量 特别要注意算 ...

  8. 《Java程序设计》第二周学习记录(1)

    目录 第2章 基本数据类型与数组 2.1 标识符与关键字 2.2 基本数据类型 2.3 类型转换运算 2.4 输入.输出数据 2.5 数组 参考资料 第2章 基本数据类型与数组 2.1 标识符与关键字 ...

  9. 《Java程序设计》第一周学习记录(2)

    目录 使用JDB调试程序 系统文件被覆盖的挽救 参考资料 使用JDB调试程序 JDB是JDK自带的基于命令行的调试程序.我们先来man一下吧(说到这里,我之前在翻娄老师的博客的时候看到一篇文章:做中学 ...

随机推荐

  1. Linux下面安装rpm包

    [root@localhost ~]# mount /dev/sdb4 /mnt/ [root@localhost ~]# cd /mnt[root@localhost mnt]# lsaddons ...

  2. linux基本知识0

    linux的基本原则: 1.有目的单一的小程序组成,组合小程序完成复杂任务. 2.一切皆文件 3.尽量避免捕获用户接口 4.配置文件保存为纯文本格式 CLI接口: 命令提示符,prompt,bash ...

  3. VS2013无法启动 IIS Express Web解决办法

    开发环境:windows8.1+VS2013 使用VS2013有一段时间了,因前期都是编写C/S程序,没有使用到B/S调试器.前几日,创建了一个MVC项目,突然发现VS2013无法调试,报了这样的错. ...

  4. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. POJ 2255. Tree Recovery

    Tree Recovery Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11939   Accepted: 7493 De ...

  6. ACCELEROMETER

    顾名思义,是加速感应器.有2种应用吧:1,电脑保护,例如当笔记本掉落时,可以被自动检测到,此时会自动关闭硬盘操作以保护数据不在强烈冲击时丢失.

  7. c# MongoDB 经纬度应用示例

    class Program      {          static string mongodb = "mongodb://127.0.0.1:27017";        ...

  8. Cookie和Session的那些事儿

    Cookie和Session都是为了保持用户的访问状态,一方面为了方便业务实现,另一方面为了简化服务端的程序设计,提高访问性能.Cookie是客户端(也就是浏览器端)的技术,设置了Cookie之后,每 ...

  9. autofac与unity注册类型的几个小区别

    //以下两个注册,在Unity中是默认的 //注册控制器,否则不管接口注入还是属性注入都获取不到服务实例 Builder.RegisterControllers(typeof(MvcApplicati ...

  10. Ajax请求示例

    模板 {% for row in host_list %} <tr> <td class="c1">{{ row.id }}</td> < ...