一、java中的对象在运行时,在计算机里是怎么存储的?
答: 寄存器、堆栈、堆、常量存储、非RAM存储
二、java中的类型、方法、参数
2.1、类型
基本类型:五类九型( boolean、char、byte、short、int 、long、float、double、void)
引用类型:继承自Object类的都是引用类型。
2.2、方法
普通方法:类似于C语言,Excle的函数。( 组合在一起来执行操作语句的集合)
构造方法: 是一个与类同名且没有返回值类型的方法。
静态方法: 若类的方法前加了static关键字,则该方法称为静态方法。
main方法: 是Java应用程序的入口方法。
静态方法和普通方法的区别:
静态方法里面直接使用不了成员变量,需要 用对象.成员变量名 进行访问和操作。
普通方法里可以使用成员变量。
方法签名:方法和参数列表组合起来,它来标识某一个方法。
2.2 、参数
形参:定义方法的时候里面的参数。
实参:调用方法中实际传进去的参数叫做实参。
参数传递分为:值传递(基本类型),引用传递(引用类型)。
值传递和引用传递的区别:
值传递在堆栈中复制一份基本类型的新key-value。
引用传递:在堆栈中复制一份指向原对象的一份新key。
可变参数列表:方法的参数个数或类型未知时,在以前的Java代码中,可以使用Object数组来实现这样的功能。因为,所有的类都是直接或间接继承于Object类。
Java1.5增加了新特性:可变参数,适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。
三、java中的变量、数据结构
3.1 变量
成员变量:在类的内部是类的组成成员。
局部变量:在方法的内部是方法的组成成员。
成员变量 和 局部变量的区别:
1、局部变量 没有访问权限 所以没有权限修饰符,它只能在方法内部使用
2、java 规定 不许有静态的局部变量 和 c有明显的区别
3、局部变量= 方法(生存周期)
4、局部变量(基本类型,引用类型) 在调用方法的时候,首先在栈内存上开辟一块空间叫做 栈贞,给局部 变量来使用,方法调用完毕然后 这块空间销毁 。
5、成员变量可以不初始化,由系统设定默认值 ;
6、局部变量没有默认值,所以必须设定初始赋值。
7、局部变量在调用方法的时候被创建
8、类实例化被创建
9、成员变量(实例变量) 放在堆内存里
静态变量:静态变量也叫做类变量,生存周期,类被回收,才死亡。
实例变量:实例变量也叫做对象变量 对象回收, 才死亡。
3.2、数据结构
(除了数组之外都可以认为是抽象的数据结构)
3.2.1、数组
优点:插入快,如果知道下标,可以非常块的存取
缺点:查找慢,删除慢,大小固定
3.2. 2、有序数组
优点:比无序的数组查找快
缺点:删除和插入慢,大小固定
3.2. 3、栈
优点:提供后进先出方式的存取
缺点:存取其他项很慢
3.2. 4、堆
优点:插入,删除快,对最大数据项的存取很快
缺点:对其它数据项存取很慢
3.2. 5、链表
优点:插入快,删除快
缺点:查找慢
四、编码规范:
类名首字母大写,其他方法,字段等小写。采用驼峰标识。
根据规则,既是static 又是 fianal的域 将用大写表示并使用下滑线,分割各个单词。
五、JAVA中的关键字
5.1、 this是指向(对象本身的一个指针)
1、规定:this(参数名) 只能用在构造方法里 意思调用构造方法
2、this.xxx xxx一定是 成员变量, 用来区分局部变量和成员变量的重名
3、this 不能用法在静态方(类方法), 静态代码块中。
5.2 、return 关键字
如果 方法定义了 类型 大括号里面最后 要加return 返回一个跟方法一样类型的值,这个值自己定义。 意思就是,返回一个结果让你来处理,或者输出,,,等。
return方法的返回值,和在返回值不为空的方法,搭配。可以导致提前导致方法结束,并返回那个值。
5.3、 lable
java中的标签功能:lable,可以跳出到标签指定的地方。
5.4、 final
java final关键字详解。(http://blog.csdn.net/yjkwf/article/details/7194569)
5.5 、length:数组 || length() :字符串 || size() :集合
5.6、String
字符串是final类型.String对象作为方法的参数时,都会复制一份引用,而该引用所指的对象从未动过。
修改字符串内容的时候,String类的方法都会返回同一个新的String对象,同时如果内容没有发生改变,String方法只是返回指向原对象的引用。可以节省空间。
打印对象:System.out.println(Object)实际上就是调用 object的toString方法。
一个字符串对象+非基本类型对象 = 字符串+ 那个对象的toString 方法,如果那个非基本类型没有重写toString 就默认加载Object的TOSTRING.
5.7、 Scanner
(详解):http://lavasoft.blog.51cto.com/62575/182467/
Scanner javase 5 版本新增的产物,大大减少扫描输入的工作,它的构造器可以接受任何类型的输入对象(InputStream),包括file对象。
5.8 、StringTokenizer
在java引入正则表达式(1.4)和Scanner(1.5)类之前,分割字符串的唯一方法是使用StringTokenizer来分词。不过有了正则表达式和Scanner,我们可以使用更简单,更加简洁的方式,完成同样的工作了。
5.9、StringBuilder
字符串总结:java更新到现在版本,对字符串的操作已经很完善了,不过有时候需要注意效率的问题了,恰当的时候使用StringBuilder.
六、常量池
常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = "java"这种申明方式;当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。
详解:http://baike.baidu.com/link?url=HH6c6DRwgIHSt5Y7dqLjiaBgzcTSoTLjGh_hxRLPOaPDjZnu6y9axt6tyZ4CU4YTIDJUADzg1TbQp9ykliB7Zmv4984EnapCvJH8wRW3b990ObClQUveQpJv0_rhRcWP
http://www.thinksaas.cn/topics/0/400/400739.html
常量池(常量) 在堆内存里 例如 :String s =new String("'sdfsfd"); 两个对象,一个在常量池里,一个在常量池外的堆内存里 注意 常量池 也在堆内存里 常量池就是在对堆内存里的一张表。
七、JAVA的操作符
7.1、几乎所有的操作符只能操作"基本类型",例外的"=","==","!="这三种能操作所有对象,除此以外String支持 "+"和 "+=".特别注意String支持"+"是连接和转换成String类型的意思。以及 字符串A += 字符串B ; 意思:字符串A = 字符串A+字符串B; 先执行右边然后赋值给左边。
7.2、赋值,"=",右面的值赋给左面的。
7.3、算数操作符:+ , -, *,/ ,%(求余数)
7.4、自动递增/减法 :++ ,--,他们放在表达式的前后。就意味着先运算,在生成和先生成,后运算。
7.5、 "=="和 "equals" 区别:没重写的equals 跟 == 没有区别,判断堆内存的地址是否相同。
7.6、短路,当使用逻辑操作符的时候,我们会遇到短路的一种想象,一旦能准确无误的整个表达式的值,就不在计算表达式余下的部分了。
举例:boolean b = test1(1) && test2(2) && test3(2); 因为是与的关系,只要test2 方法 是false,这个表达式就会等于false。就没有必要在执行test3方法。
7.7、 java的按位操作符(直接对整数在内存中的二进制位进行操作运算)
详解:http://www.cnblogs.com/dongpo888/archive/2011/07/13/2105001.html
7.8、Java的位运算符详解实例(对二进制数位进行逻辑运算)
http://blog.csdn.net/is_zhoufeng/article/details/8112199
7.9、 java 三元运算符: i > 10 ? i * 100 : i * 10; 条件?ture :false (满足条件,就执行ture的,不满足就执行false)
7.10、 逗号操作符:用户方法的里面的参数的分割,和在For循环的语句内,定义个多个变量,但是他们必须具有相同的类型。
7.11、!则是一个一元运算符,运算对象是boolean类型。若运算对象为true则返回false,若运算对象为true则返回false。
八、JAVA核心概念:多态
多态:(方法的重写、重载与动态连接构成多态性)
8.1 、多态分两种:
(1)编译时多态(设计时多态):方法重载。
(2)运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。(动态调用)
运行时多态存在的三个必要条件:
一、要有继承(包括接口的实现);
二、要有重写;
三、父类引用指向子类对象。
8.2、java 中继承和组合
http://www.importnew.com/12907.html 。
继承:如果没有明确指定父类,那就是Object的子类。
子类会默认调用父类(基类)的无参构造方法。如果想调用父类带参数的构造方法,需要super(i) 方法,并且配已适当的参数(i)列表。
8.3、重写:必须有继承并且只改变方法体里的内容;
重载:必须在同一个类里并且有不同的参数列表。
8.4、java的 向上转型和向下转型( 父类引用指向子类对象)
http://blog.csdn.net/mr_jj_lian/article/details/6860845
8.5 、Thinking in java 部分笔记
http://www.cnblogs.com/lanxuezaipiao/p/4153070.html
九、抽象类、接口、内部类
9.1、 抽象类
含有抽象方法的类。(抽象方法:没有方法体的方法)。用abstract关键字修饰。
9.2、 接口
方法的特征集合并实现了多继承机制。用 interface 关键字修饰。
嵌套接口:接口可以嵌套在类或其他接口(备注:javac 出错NoClassDefFoundError,去掉包名就可以)
a、class嵌套interface:这时接口可以是public,private和package的。
b、interface嵌套interface:被嵌套的接口必须是public。(由于接口默认是public)
9.3、抽象类与接口的区别
抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。
9.4、内部类
一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类,
java 内部类:http://www.cnblogs.com/dolphin0520/p/3811445.html
匿名内部类( 没有名字的内部类)
http://blog.csdn.net/chenssy/article/details/13170015(当所在的方法的形参需要被内部类里面使用时,该形参必须为final)
闭包与回调:通过内部类提供闭包功能。( 闭包:相当于内部类。回调:非常灵活,可以运行时动态决定调用哪个方法)
内部类的继承:extends 外围类.内部类 然后在 子类构造方法里 传外围类参数.super();
十、正则表达式
10.1、正则表达式
解释:如果一个字符串含有这些东西,那么它就是我正在找的东西。
详解: http://blog.csdn.net/allwefantasy/article/details/3136570
java 中的 "\\" :我要插入一个正则表达式的反斜杠。
split 详解:String 包下的 split方法,详见 api .
正则表达中数量词:Greedy(贪婪) Reluctant(勉强) Possessive(独占) 的区别 (http://blog.csdn.net/luoweifu/article/details/42759439 )
捕获组与非捕获组:http://mcj8089.iteye.com/blog/1183075
非捕获组详解: http://blog.csdn.net/is_zhoufeng/article/details/7645366/#comments
java 7 新特性:命名捕获 与匹配原理(http://blog.csdn.net/su1216/article/details/49407381)
正则表达式:各种字符与转义字符说明:http://blog.csdn.net/alexbxp/article/details/7002782
10.2、案例
String addr="Ribbon Cartridges for Brother Fax 1200991P Printer ml 2013d sd 4544ab 7878A "
// 从字符串addr从左往右的5个数字后面 插入$1后面的字符串。
addr = addr.replaceAll("(\\d{5}){1}","$1 HELLO");
详解: (\\d{5}) :取值范围为[0-9]5个数字的一个捕获组。
{1}:代表BACK 引用,例如(ab)34(cd)\1\2就表示ab34cdabcd. java的正则表达式里在捕获组后面用{1}代替\1。
start() 与 end():在匹配成功之后,start()返回先前匹配的起始位置的索引,而end() 返回所匹配的最后字符的索引加一的值。
reset() 将Matcher 对象应用于新的字符序列。
10.3、格式化输出
printf()和format() System.out.printf/format();
Formatter:
http://lavasoft.blog.51cto.com/62575/179081/
http://lavasoft.blog.51cto.com/62575/184492/
10.4 nodepad++ 正则(替换数字为空格)整数:[1-9]\d*
十一、数组、容器 、泛型
11.1 数组
数组只是相同类型的、用一个标识符名称封装到一起的一个对象序列或基本数据类型序列
就是相同数据类型元素按一定顺序排列的的有限集合。
要定义一个数组在类型后面加上一对空方括号即可。
数组详解:http://www.52ij.com/jishu/java/98820.html
java 数组是从零个元素开始,所有能使用的最大下标数是 lenth-1.
尽量数组在定义的时候,进行初始化。
对象数组初始化:http://blog.csdn.net/robinlovesnow/article/details/4672927 。 (其中要注意的问题。)
11.2 容器
11.2.1 、概念
容器是一个Java 所编写的程序,原先必须自行编写程序以管理对象关系,现在容器都会自动帮您做好。
容器(http://blog.csdn.net/xczheng/article/details/3936474#comments)
用途:保存对象。
由Collection 和Map 组成。
Collection中的list必须按照插入的顺序来保存元素,而set不能有重复元素等。
Map:"键值对"对象。
11.2.2、 Collection
填充容器:1、http://blog.csdn.net/raylee2007/article/details/50401373
2、http://blog.csdn.net/raylee2007/article/details/50402983
3、http://blog.csdn.net/raylee2007/article/details/50411324
Collection层次结构与功能方法 http://blog.csdn.net/itlwc/article/details/10148321
Collection 可选操作(optional operation ): http://blog.csdn.net/luo110556/article/details/50497182
容器类总结(http://www.cnblogs.com/wishyouhappy/p/3669198.html)
跟Arrays 一样 容器类也有对应的工具类:Collections。
java 持有引用(垃圾回收):http://blog.csdn.net/mazhimazh/article/details/19752475
11.2.3 、List
概念: 有序的 collection(也称为序列)。
java List 详解:http://www.open-open.com/lib/view/open1426161465810.html
Java list排序和查询 :http://baike.xsoftlab.net/view/208.html#2_1
11.2.4 、Set
概念: 一个不包含重复元素的 collection
java Set详解:http://blog.csdn.net/arron_12/article/details/52072603
11.2.5、队列
概念:一种先进先出的数据结构:除了并发引用,Queue在JAVA 5 中仅有两个实现是LihkedList 和PriorityQueue,他们的差异在于排序行为而不是性能。
队列详解: http://hellosure.iteye.com/blog/1126541
java自带线程池和队列详细讲解: http://www.oschina.net/question/565065_86540
优先级队列: http://blog.csdn.net/hiphopmattshi/article/details/7334487
双向队列:http://blog.csdn.net/jjwwmlp456/article/details/40377459?utm_source=tuicool&utm_medium=referral
11.2.6 、Map
概念: 将键映射到值的对象。
java中map详解:
http://www.52ij.com/jishu/java/99025.html
java中map排序详解:
http://www.jb51.net/article/44015.htm
散列/散列码:
http://blog.csdn.net/liangrui1988/article/details/30756299?utm_source=tuicool&utm_medium=referral
简单HashMap实现散列映射表执行各种操作案例详解:
http://blog.csdn.net/liangrui1988/article/details/30756299?utm_source=tuicool&utm_medium=referral
Map 和Map.entry :(entry) 是Map的内部接口: http://www.cnblogs.com/guanjie20/p/3769772.html
Map遍历:(4种遍历方法)http://blog.csdn.net/tjcyjd/article/details/11111401
11.2.7、常见容器选择:
List选择:
查询用ArrayList,插入、删除用LinkedList.
最佳选择:将ArrayList作为默认首选,只有你需要额外的功能或者经常从表中间进行插入或删除性能变差的时候,才去选择LinkedList。
如果是固定的元素既可以使用有背后数组支持的List(就像Arrays.asList()产生固定大小的列表) ,也可以选择真正的数组。
Set选择:
最佳选择是HashSet,只有需要一个排好序的Set并且要迭代的话选择TreeSet。
Map选择:
最佳选择是HashMap,只有需要一个排好序的 Map并且要迭代的话选择TreeMap。
随着Map尺寸的变大时又不影响其插入性能,可以选择IdentityHashMap。
(备注: 除了IdentityHashMap,其他Map,都是尺寸变大,插入越慢。)
WeakHashMap 解决HashMap,内存性能问题
详解: http://www.cnblogs.com/skywang12345/p/3311092.html
11.2.8 容器保护
设定Collection和Map为不可修改只要已修改,就会报 UnsupportedOperationException。
可以用Collections中的方法 ,具体详见:JDK 1.6 api :java.util.Collections包下的各种容器不可变方法。
Collection或Map的同步控制:
Collections其中有方法能够自动同步整个容器: 可以用Collections中synchronizedXxx 方法 (Xxx:为具体的List或者Map)
具体详见:JDK 1.6 api :java.util.Collections包下的容器的线程同步方法。
快速报错:
java容器有一种保护机制,能够防止多个进程同时修改同一个容器的内容。
java容器类库采用快速报错(fail-fast)机制。他会探查上的任何除了你的进制所进行的操作以外的所有变化,一旦它发现其他进程修改了容器就会立即抛出ConcurrentModificationException(当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常)。
java快速报错详解:http://www.cnblogs.com/skywang12345/p/3308762.html
http://www.2cto.com/kf/201403/286536.html
11.3 、泛型
概念: 所谓“泛型”,就是“宽泛的数据类型”,任意的数据类型。
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型
(注意:泛型支持多态,即可以存入该类型的子类)
泛型详解 :http://www.weixueyuan.net/view/6321.html
泛型类(Java Class),它可以接受任意类型的数据:class Xxx<T1, T2>,多个类型参数用逗号隔开。
类型参数: <T1, T2>,T1, T2 是自定义的标识符(一般使用单个大写字母),也是参数,我们称之为类型参数。
注意:任何基本类型都不能作为类型参数.
泛型方法:定义泛型方法需要把类型参数放在修饰符后面、返回值类型前面。
不必指明方法的参数类型,编译器会根据传递的参数自动查找出具体的类型。( public <T1, T2> void/T xxx(T1 x, T2 y){})
具体详解:http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html
泛型接口:定义接口时后面跟个Yyy<T>. 实现泛型接口:class Xxx<T> implements Yyy<T>。
类型擦除:使用泛型时没有指明数据类型,为了不出现错误,编译器会将所有数据向上转型为 Object。取出的时候出问题,得做向下转型才行。
举例:List在API里就是泛型接口。ArrayList是泛型类,都它么使用了泛型,往里面存东西的时候,没有明确指定类型,进去的都是Object,取出来就得做强制转换(也叫向下转型)。
边界(限制泛型的可用类型):extends 、super关键字可以限制泛型的类型:<T extends Number> 、<? extends Number> (extends是上界) and <T super Number>、<? super Number>(super是下界)
通配符
(使用<T>来声明类型持有者名称,自定义泛型类时,类持有者名称可以使用T(Type),
如果是容器的元素可以使用E(Element),若键值匹配可以用K(Key)和V(Value)等,若是<?>,则是默认是允许Object及其下的子类,也就是java的所有对象了)
元组:一次方法调用就能返回多个对象,概念就是将一组对象直接打包存储于其中的一个单一对象,这个容器允许读取其中的元素,不允许向其中存放新的对象。
想要更长的元组:利用继承机制。
使用元组:定义一个长度适合的元组,将其作为方法的返回值,然后再return语句中创建该元组,并返回即可
举例:http://www.pocketdigi.com/20131115/1202.html
构建复杂模型:http://blog.csdn.net/raylee2007/article/details/50285781
泛型擦除 :(http://blog.csdn.net/lonelyroamer/article/details/7868820#reply)
擦除的补偿:(编译器将确保类型标签可以匹配泛型参数 ):http://blog.csdn.net/liangrui1988/article/details/28497249
11.4 数组与泛型
详解:http://blog.csdn.net/orzlzro/article/details/7017435
数组与泛型不能很好的结合,你不能实例化具有参数化类型的数组。
编译器不让实例化泛型数组,但是它允许创建泛型数组的引用,然后在创建一个非泛型数组,然后将其强制转型成泛型数组。
举例: List<String> [] ls; //可以创建一个泛型数组的引用。
List[] la = new List[10]; //创建一个非泛型数组。
ls = (List<String> [])la; //强制转型
ls [0] = new ArrayList<String>();
Object[] objects = ls;
objects[1] = new ArrayList<Integer>();
说明:不会涉及到向上转型,需求简单,可以用它。事实上泛型容器才是更好的选择。
11.5、 泛型和类型安全的容器。
举例:ArrayList因保存的是Object,神马类型都能存。所以编译期不会出错。
get取值的时候,就会出错,因为取出的是Object引用,必须要强制转型(向下转型)才可以获得其本身属性和方法。
安全的容器:定义泛型<对象1,对象2...>通过定义泛型,可以在编译器防止 将错误的对象放到容器中。
具体案例:(http://blog.csdn.net/wangyunyun00/article/details/38404861)
十二、IO
概念: 流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作
IO详解 :http://blog.csdn.net/jiangwei0910410003/article/details/22376895
http://blog.csdn.net/yczz/article/details/38761237
NIO详解:http://ifeve.com/overview/
http://www.iteye.com/topic/834447
BIO,NIO,AIO区别:http://qindongliang.iteye.com/blog/2018539
十三 、异常
基本理念:结构不佳的代码不能运行。
详解: http://blog.csdn.net/hguisu/article/details/6155636
处理目标:java中异常处理的目的在于通过使用少于目前数量的代码来简化大型、可靠程序的生成.
补充:finally 核心是清理,清理范围;除内存之外的资源恢复到他们的初始状态,就要用finally
例如,已打开的文件或网络连接等,在finally块中写关闭文件,和关闭网络连接的代码来释放资源。
异常链:捕获一个异常后抛出另一个异常 ,并把原始的信息保存下来。http://blog.csdn.net/touch_2011/article/details/6860043
十四、控制语句和遍历
14.1、Foreach语法: for(float x :f) ,定义一个变量x,继而将每一个f的元素赋值给 x。
(任何返回一个数组的方法,都可以使用),可以应用到任何Iterable对象。
14.2、循环:while(条件=true){执行} 条件=false时跳出执行。
do{执行} while(条件=true) 条件=false跳出执行。
14.3、迭代语句主体都可以用 break,continue 来控制流程。
break:强制退出当前循环。 continue:停止当前的迭代,进行下一次迭代。
14.4、Java 7中 switch里面已经允许使用int,char,和enum、和字符串类型。
14.5、迭代器(是一种设计模式):他的工作是遍历并选择序列中的对象。
14.6、ForEach 用于遍历数组 和Collection对象。
14.7、遍历数组和集合(http://blog.csdn.net/iamkila/article/details/7266890)
十五、并发
并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行
但任一个时刻点上只有一个程序在处理机上运行。
Java并发与多线程教程:
1、http://blog.csdn.net/zhoudaxia/article/details/24294583
2、http://blog.csdn.net/zhoudaxia/article/details/24422025
3、http://blog.csdn.net/zhoudaxia/article/details/24606877
详解: http://ifeve.com/java-concurrency-thread-directory/
Java多线程编程总结 http://lavasoft.blog.51cto.com/62575/27069/
十六 类型信息
概念:运行时类型信息,使得你可以在程序运行时发现和使用类型信息。
16.1、ClASS类
概念:Class
类的实例表示正在运行的 Java 应用程序中的类和接口。
详解 : http://lavasoft.blog.51cto.com/62575/15433 具体方法详见api
16.2 类字面常量
java提供了另一种方法来生成对class对象的引用,Object.class 这样做不仅简单还更安全,因为在编译期间,就会受到检查。类字面常量不仅可以普通的类,也可以用于接口、数组、基本数据类型。还有一个标准字段TYPE . TYPE字段是一个引用,指向对应的基本数据类型的CLASS对象 如下: byte.class 等价于Byte.TYPE
16.3、.class 使用它来创建Class对象的引用时,不会自动初始化该Class对象,需要经过三步
1、加载(查找字节码、创建一个Class对象))
2、链接(验证类中字节码 ,为静态域分配存储空间)
3、初始化(如果具有超类、则对其初始化、执行静态初始化块)是有延迟的,具体说明如下:
初始化被延迟到了对静态方法或者非静态域进行首次引用时候才执行。
所以一个static域不是final的那么在访问它的时候,先进行链接和初始化。反之如果是一个static final 的域,直接读取和加载,然后在进行链接和初始化。
注意:static final int = 1; 属于编译期常量,不需要类初始化就可以读取。
Thinking ih java 代码: ClassInitialization
16.4、 泛化的Class引用:
Class引用表示的是它所指向的对象的确切类型,而该对象便是Class类的一个对象。在JavaSE5中,可以通过泛型对Class引用所指向的Class对象进行限定,并且可以让编译器强制执行额外的类型检查:
Class intCls = int.class;
// 使用泛型限定Class指向的引用
Class<Integer> genIntCls = int.class;
// 没有使用泛型的Clas可以重新赋值为指向任何其他的Class对象
intCls = double.class;
// 下面的编译会出错
// genIntCls = double.class;
RTTI,Class,泛化的Class引用详解:http://www.itzhai.com/java-notes-rtti-class-generalization-of-class-references.html#read-more
16.5、类型信息与反射机制
http://263796001-qq-com.iteye.com/blog/1225316
反射机制概念: 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
反射详解:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
16.6、java类型信息小结
1.使用RTTI解决多态中的问题--知道某个泛化引用的确切类型
2.Java中的类加载是动态加载的,“当程序创建第一个对类的静态成员的引用时,就会加载这个类”,“使用new操作符创建类的新对象也会被当做对类的静态成员的引用”。类加载是就会执行static初始化,即为static变量赋值和执行static程序块。另,JDBC中用到的Class.forName("XXXX")就是为了加载类,使用.class不会引发初始化。
3.static final的编译期常量无需类初始化就可以读取,但如果不是常量,则需要类先初始化。
4.使用Class类的引用可以获取某个类的信息,其中需要注意的:
a)newInstance()方法实现了“虚拟构造器”,但类必须要有无参构造器(可以不是默认的)。
b)泛化Class引用中,Class<?>优于平凡的Class;Class<? extends XXXX>或Class<? super XXXX>可以强制类型检查;使用.getSuperclass()方法获取的超类后使用.newInstance()的返回值只是Object类型。
c)转型前的检查,可以使用关键字instanceof,如:if(x instanceof Dog) ...,Class的isInsance()方法有同样效果,但后者的Class类型可以使用变量,而前者只能写死。
d)类型检查时,使用==或.equals()方法只能判断类型是否相同,但使用instanceof或isInstance()则包含了继承关系。
5.动态代理,使用静态方法Proxy.newProxyInstance()可以创建动态代理的实例,三个参数分别为:类加载器、期望代理实现的接口列表、InvocationHandler接口的一个实现。在第三个参数中,可以实现方法过滤(使用代理的好处之一吧,感觉像是代理在操控情报。。。腹黑一下),也可以实现事务。
6.反射可以违反访问权限进行操作。
16.7、java 类型信息 instanceof 和 isInstance区别 :
http://blog.csdn.net/edmond999/article/details/45533899
http://www.cnblogs.com/greatfish/p/6096038.html
16.8 、java的动态绑定与双分派(规避instanceof)
http://www.cnblogs.com/liaokailin/p/3804437.html
16.9、java注册工厂(源码实现)
http://blog.csdn.net/eric_sunah/article/details/7240770
16.10、java 空对象模式
http://blog.csdn.net/qiumengchen12/article/details/44923139
java23种设计模详解
http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.htm
设计模式: 是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性
十七 枚举类型
概念:关键字enum可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能.
详解:http://www.cnblogs.com/hemingwang0902/archive/2011/12/29/2306263.html
十八 代理
概念:调用真正业务之前或者之后做一些“额外”业务。
从服务类中抽出来公共服务接口。代理类实现公共服务接口,且传入需要的服务类,完成特定的服务以及增加额外的服务。
为什么要用代理? 因为不想直接引用一个对象。
静态代理:缺点统内的类的规模增大,并且不易维护。
动态代理:就是不希望有很多代理类出现,一个就动态的代理类就可以了。然后搞了个接口InvocationHandler 接口 和Proxy 类来实现这一目标。
创建动态代理类过程,首先1、xx通过实现InvocationHandler接口与它里面唯一的方法invoke方法。
2、然后通过Proxy类调用newProxyInstance方法,把服务类传给xx,并且返回一个xx对象。
3、然后服务接口 a =(服务接口)xx对象 强制转型为服务接口。
4、服务接口a.服务方法的时候,就会通过jdk底层反射机制,跳回到xx执行xx中的invoke方法。
代理与动态代理详解 :http://www.blogjava.net/interface/archive/2008/01/04/172841.html?opt=admin
动态代理详解 :http://www.cnblogs.com/xiaoluo501395377/p/3383130.html
深入理解动态代理:http://blog.csdn.net/luanlouis/article/details/24589193