JAVA细节上的特别之处
来源:互联网 发布:网络热词排行榜2017 编辑:程序博客网 时间:2024/04/29 04:00
JAVA有吸收C,C++的优点,同时某些方面又添加了自己的特点
1关于注释
除了单行,多行注释,又添加了
文档注释
利用javadoc可以生成相应的API文档
2java默认UNICODE字符集,可以用中文日文表示标识符
3goto,const是保留字,true,false,null是直接量,再加上48个关键字,都不可以作为标识符
4基本数据类型有boolean,byte,char,short,int,long,float,double,此外其他都是引用类型
JAVA7新增加了二进制数字类型,例子int binNum=0B10101011;// 0b或0B
JAVA7用下划线可以分隔数字,例子double pi=3.14_15_92_65_36;// 只是为了防止看错
5移位运算符添加>>>无符号右移
>>是算术移位,>>>是逻辑移位
6关键字instanceof
7switch在JAVA7中,新增了String类型
8break,continue可以用标签(类似goto功能的标号)进行外层循环的跳出
9数组类型
JAVA5增加了foreach的循环,例子for(Class o:oSet)// oSet是数组,array,set等集合,其中o只是开辟的临时变量,并不是数组中真正成员,在循环体中赋值要注意是否有效
10java.util.Arrays类
binarySearch
copyOf
equals
fill
sort
System.arraycopy
11初始化是创建一种引用,new后将引用与新对象进行关联;
基本类型对应的包装类型,作为类中成员变量时的初始化默认值(而局部变量中的默认值是任意值,这与C一致)
boolean Boolean
false
char Character
\u0000(null)
byte Byte 0
short Short 0
int Integer 0
long Long 0L
float Float 0.0f
double Double 0.0d
void Void
在创建数组对象时默认创建引用数组,并初始化为null(与C++的区别,C++会执行默认构造函数,创建在栈空间中);
12JAVA有类似C中的作用域屏蔽变量的概念(实际上屏也是因为默认省略了成员变量前的this或static),最好用对象将其区分开,static,this修改对象
13package名类似于域名,只不过是反转过来使用的(例如com,edu,org,net)
13,JAVA没有sizeof(因为不需要底层移植了)
14非零值无法表示布尔true(与C++不同),因为JAVA中的数值与boolean不能转换,boolean可以用"true"字符串来转换
15this的使用,static成员的使用
16JAVA方法中参数传递都是值类型,但由于非基本类型都是引用类型,所以值传递过来,形参=复制值生成新的引用,形参与实参操作的都是同一对象,所以修改形参的属性将会影响调用方法原形参的属性,但将实参=null,并不影响形参,想想看为什么!
17可变个数形参,例子void test(int a,String ... params){}//只能是形参列表最后一个,只能有一个,传递时可以传入数组
18对象可以访问static成员(即使置为null后),但最好直接用类名来操作static,概念和可读性都佳
19访问控制符级别private>default>protected>public
20import,JAVA默认导入了java.lang下的所有类,import static可以导入static类或成员
21常用package
java.lang:String,Math,System,Thread
java.util:Arrays,List,Set
java.net
java.io
java.text
java.sql
22构造函数中用this(param,...)调用另外一个构造函数
23JAVA实行单继承extends,只能直接继承一个父类,所有类都派生于java.lang.Object
24JAVA中的函数无法继承,只能显示的super.constructer();
25JAVA初始化块,
初始化块与成员的默认值先后是由书写顺序决定,
初始化顺序是:基类static初始化块,类static初始化块(static只在加载类时执行一次),基类初始化块,基类构造,类初始化块,类构造
26基本数据类型的包装类,对值的判断应该用compare方法,==有时会不一置
27final成员,
系统不会隐式初始化,程序员初始化后其值不可改变(只能赋值一次),修饰形参不能赋值(可以理解为C中的const)
修改引用类型时,引用变量可以修改其对象数据,但不能指向其他对象了
28final变量在定义时指定初化值,且编译时就能计算确定下来(表达式中没有调用类方法),则所修饰变量将会转化为常量
final方法可以重载,子类不能重写父类的final方法,这与子类定义父类同名的private方法区别:后者是新写了一个名字相同的方法,前者编译器不允许,private final执行private原理
final类无法继承
29abstract抽象类,不能实例化,可以理解成子类的模板,设计的雏形
abstract抽象方法,子类必须得重写(除非又是一个抽象子类)
可以有成员变量,可以有成员方法,可以有static方法和常量,可以有构造和初始化块
abstract和final,static,private不能同时用
30interface接口,不能包含普通方法,所有方法都是抽象方法,可以理解成子类的规范,系统的纲目
接口可以多继承,只包含构造和初始化块,只能有常量成员public static final,只能有抽象方法public abstract,内部类,枚举public static
31implements可以多实现
32内部类
静态内部类:外部类加载时,静态内部类不会被立即加载(可以借此实现单例),内部方法不能访问外部类对象成员(只能访问静态成员方法)
非静态内部类:利用这个实现JAVA中的闭包,必须由外部类对象来创建,不能有静态成员,静态块,静态方法
局部内部类::不能使用static修饰
匿名内部类:必须继承一个父类或实现一个接口(最多一个),创建后,类定义生成一个实例,同时类定义消失,不可复用;访问外部类的成员,必须被final修饰
33枚举类
enum,每一个枚举量就是一个实例
含有抽象方法的enum类会自动提升为抽象类,同时在枚举值中必须实现抽象方法(类似匿名内部类的实现,直接产生实例)
非抽象枚举类默认被final修饰,因此不能派生子类
34GC
GC负责堆中不再引用的空间回收,IO资源不处理
无法精确控制
GC执行之前会调用finalize()
引用变量三种状态
可达,可恢复,不可达
System.gc(); Runtime.getRuntime().gc();
System.runFinalization();//强制执行finalize(),不建议使用
35软,弱,虚引用
强,默认引用
软,内存不足时会回收
弱,GC时可能会回收
虚,只有虚引用时,几乎就是没引用,必须和引用队列联合使用(通过检查与虚引用关联的引用队列中是否已经包含了该虚引用,从而了解虚引用的对象是否即将被回收)
java.lang.ref
recreateIt()
36Scanner获得键盘输入:hasNextXXX,nextXXX
37BufferedReader new BufferedReader(new InputStreamReader(System.in));//
38System: getenv,getProperties,currentTimeMills(),nanoTime(),in,out,err,identityHashCode,
39Properties
40Runtime:getRuntime(),exec
41Object:equals,finalize,getClass,hashCode,toString,clone(类似于浅拷贝),wait,notify,notifyAll
42Objects工具类,JAVA7添加,其大多方法是null指针安全
requireNonNull验证参数,不空返回参数,空则引发异常
43
String是不可变类
compareTo,返回字母差或长度差(前段串均一致的情况下)
StringBuffer线程安全
StringBuilder线程不安全
append,insert,replace,delete,reverse,length,setLength,capacity
44
Math
45
Random
ThreadLocalRandom是JAVA7添加的并发环境优化的随机数生成类,用current()获得对象
46BigDecimal为了防止精度丢失,不建议使用double数来创建对象,最好用String或BigDecimal.valueOf来创建,防止数在double参数赋值时会被改变值
47Calendar,getInstance()
注意add和roll的区别,前者带进位,后者不进位,进位过程中出现不合逻辑的日期(如每月天数不一致,月计算后就会造成日不合逻辑),日期将向修正到变化最小的值
setLenient设置是否宽容,true表示宽容,超过范围后将进位
set方法会延迟修改,延迟到下次get或add roll的时候
48TimeZone
49正则表达式:是一个用于匹配字符串的模板,利用这个模板可以匹配一批字符串
matches
replaceAll
replaceFirst
split
Pattern不可变类,Pattern.compile(regex);
Matcher,p.matcher(str);m.matches();
50
I18N与I10N
ResourceBundle
Locale
MessageFormat,NumberFormat,DateFormat
SimpleDateFormat
51集合类
Collection中保存的是引用,操作的是对象
Set不允许重复的容器,重复是指的equals,值相等,即使引用不等,也会add失败
Queue
List
Map
HashMap
TreeMap
HashTable
Iterator
迭代时传递的是元素的值,修改其变量并不能改变集合内的元素
迭代中不允许remove元素
HashSet是不允许hashCode重复的容器,值重复但hashCode不同可以add,但理论上重写应保证 值 与hashCode保持一致,
HashSet中添加可变对象注意,在修改该对象时可能造成hashCode改变为另外一个已有对象的hashCode,而导致HashSet无法定位准确的对象
LinkdedHashSet带有插入顺序的hashSet
TreeSet(SortedSet):如果添加对象集合到TreeSet,一定要实现该类的Comparable接口compareTo方法,因为没有默认规则,compareTo为0则无法添加,理论上重写应保证equals与compareTo保持一致
添加可变对象的问题与HashSet类似
EnumSet
上述Set都是线程不安全
List是有序,可重复,带有索引的集合,List判断对象相同的标准是equals
ListIterator,可以向前迭代previous
ArrayList,默认initialCapacity为10,如果确定要添加大量元素,可以ensureCapacity(minVal)一次性增加该值以减少扩充容量的性能损耗
相应地有trimToSize减少空间
线程不安全
注意Arrays.asList得到的ArrayList是内部类实例,不可变
子类LinkedList实现了List和Deque
Vector线程安全,但较古老不建议使用,有子类Stack
Queue
PriorityQueue
Deque其实现类有ArrayDeque ,LinkedList
Map// JAVA实际是先实现了所有的Map子类,然后包装成value都为null 的集合实现了Set集合类
Entry
HashMap, initialCapacity初始化容量loadFactor装载因子,
LinkedHashMap
SortedMap
TreeMap
WeakHashMap
IdentityHashMap要求两个key严格相等时才算相等(key1==key2)
Hashtable较古老,不建议使用,线程安全,不允许用null作key,value但HashMap允许
Properties是Hashtable的子类
Collections,操作集合的工具类,可以进行排序,查找,替换,
shuffle对List中元素随机排序
binarySearch
max
fill
frequency
indexOfSubList
replaceAll
同步控制Map m=Collection.synchronizedMap(new HashMap());
返回不可变集合emptyXxx();singletonXxx();unmodifiableXxx();
BitSet古老的集合
Enumeration古老的迭代器,类似Iterator,用来遍历古老的集合
52泛型
泛型T不同,仍然是同一个类,因为不能添加静态T成员,不能在静态方法中使用T参数,instanceof后不能用泛型类
类型通配符?
?表示容器中的泛型是各种泛型的父亲,用通配符作泛型参数的集合,不能修改其中的元素,因为不确定是什么类型的元素
? extends Class表示容器中的泛型是继承于Class的,也可以是Class本身,相当于设定上限
? extends Class & interface 设定多个上限或接口
static <T> void func(T[] a,Collection<T> c)泛型方法,与普通方法相比,多了类型形参的声明,<T>用尖括号,多个类型如<T,S>用逗号隔开,所有类型形参声明放在修饰符和返回值之间
泛型方法和通配符使用的区别
泛型方法允许类型形参被用来表示方法的一个或多个参数之间的类型依赖关系,或者方法返回值与参数之间的类型依赖关系,如果没有依赖,就不应该使用泛型方法,而使用通配符
通配符用于形参时,不可以向集合中添加元素,也不可以修改元素
通配符还可以在定义变量时表示类型,泛型方法只能在方法中显式声明
通配符在方法中声明类型相对经清晰和准确
泛型构造器
public <T> Class(T t)
{
}
new Class("abc"); // 隐式构造String
new <Integer> Class(123);// 显式构造Integer
? super Class// 通配符设定下限
类型擦除,当带有泛型信息的对象赋给没有泛型信息的变量时,尖括号的类型信息会被擦除,例如List<String>给List,会变成List<Object>
反过来赋则只是"未经检查的转换"
泛型与数组
数组元素不能包含类型变量或类型形参,除非是无上限的通配符,
但是可以声明,例如可以声明List<String>[]的数组,不能创建ArrayList<String>[10]的数组对象
也就是说不能利用泛型数组
53异常
try中是一局部块
catch按顺序捕捉,出现异常后,后面的将不再捕捉,因此先"小异常"再"大异常"(先子类异常再父类异常)
finally一定执行,异常中即使return也会执行finally,但如果用System.exit(1),则会跳过,
通常不要在finally中添加return或throw语句,因为这样会造成try,catch中的return ,throw失效,
JAVA7中添加了自动关闭资源的try语句
throws向上抛异常,子类方法抛出的异常应该是父类方法抛出的异常的子类或相同
自行抛出异常用throw,checked异常需要在try catch块或向上throws中,
而Runtime异常就不需要,更加灵活
54annotation
55
File类
deleteOnExit当虚拟机退出时执行删除
FilenameFilter接口
流
InputStream字节流
OutputStream
Reader字符流char(16位=两个字节)
Writer
FileInputStream
FileReader
ByteArrayInputStream
CharArrayReader
PipedInputStream
BufferedInputStream
BufferedReader
ObjectInputStream
RandomAccessFile,getFilePointer,seek,构造函数中的mode有r,rw,rws,rwd
Serializable序列化
反序列化时并没有调用构造器来生成对象
一个文件多次序列化,则反序列化的顺序应保持一致
序列化可变对象时,第二次写入改变的对象,将只输出原对象的序列化编号,也就是说再读取出来时,值始终保持第一次写入的状态
递归序列化
在关键字前增加transient可以不序列化此成员变量
自定义序列化方法writeObject,readObject,readObjectNoData //可以利用这点进行流加密解密
writeReplace序列化对象替换,readResolve读取,主要应用于单例类,枚举类的序列化
序列化的版本long serialVersionUID
56
Buffer,ByteBuffer,CharBuffer,MapedByteBuffer,通过allocate申请,allocateDirect可以申请直接ByteBuffer,性能更高,一般用于长期生存的Buffer
flip(),clear()
Channel只能与Buffer交互,没有构造器,是从InputStream类getChannel()获得,然后map()成为MappedByteBuffer后输出,或者重载read,write
57
Charset,forName(),encode(),类似String中的getByte(String charset)
CharsetEncoder,CharsetDecoder
58
FileLocak
从FileChannel从lock/tryLock获得文件锁,前者阻塞,后者非阻塞,release释放锁
共享锁,排他锁
59多线程
Thread,currentThread获取当前线程,Thread类不能共享数据,不能再继承其他类
Runnable接口,实现该接口的类,可以继承类,其同一对象可以在多个线程中同时运行,从而可以共享数据
JAVA5 新增Callable类似Runnable,用,FutureTask 包装Callable,然后放入Thread中运行,可以根据,FutureTask 对象.get()获得相应的返回值
sleep()进入阻塞,移植性比yield强
yield()进入就绪
start()进入就绪
stop()进入死亡(容易死锁)
resume()阻塞到就绪
suspend()运行到阻塞,(容易死锁)
isAlive()
join()等待join线程执行完
Daemon守护线程,在前台线程执行完后,后台线程会自动锁毁
setDaemon(true)
守护线程创建的依然是守护线程
子线程优先级与父线程优先级相同,默认情况下
Thread.sleep(1)的作用是将时间片让度给其他线程,用1ms的时间停止当前线程的执行,让CPU重新分配时间片
synchronized(obj)// 同步监视器
{
}
同步锁,obj一般是共享资源,设置临界区
同步方法的同步监视器是this
Object类
wait()方法会释放当前同步监视器synchronized的锁定
notify()
notifyAll()
这些操作类似操作系统概念中的PV锁同步操作顺序,LOCK类似PV锁共享资源
Lock接口,ReadWriteLock接口
ReentrantLock
Condition类似Object类中
Condition cond=lock.newCondition();
await
signal
signalAll
信号量操作
BlockingQueue
生产者向其装载数据,满时会阻塞
消费者取数据,空时会阻塞
ThreadGroup
Executors工厂类,线程池
ThreadLocal线程局部变量,为每个线程提供变量副本
ConcurrentHashMap高效并发的实现类
CopyOnWriteArrayList写操作靠复制数组,读操作很快
60网络操作
InetAddress
URLDecoder
URLConnection
ServerSocket
Socket,setSoTimeout是设定工作超时,socket.connect(ip,timeout)这里的timeout是连接超时
shutdownInput半关闭
shutdownOutput
DatagramSocket
receive(dp)
send(dp)
DatagramPacket
MulticastSocket用于接收的多播必须指定一个端口
joinGroup
leaveGroup
setTimeToLive(int ttl)//设置packet 可以经历多少个子网,0表示本机,1是局域网
Proxy
ProxySelector
61JAVA代码被编译成class,class或JAR或网络资源会被加载到JVM中形成java.lang.Class对象,在链接后才开始初始化,final常量仅作类似的宏替换,其相关代码并不会触发类的初始化
ClassLoader
loadClass并未初始化
forName初始化了
findClass
getParent返回父类加载器
getSystemClass
findLoadedClass
三种类加载器
Bootstrap非ClassLoader的子类,是JVM的一部分,不是JAVA实现的
Extension
System
加载机制
全盘负责
父类委托
缓存机制
URLClassLoader是扩展类加载器的父类
Class类
Class对象可以get获得Filed,Method,Constructer,Annotation,Class(内部或外部类),Modifier(修饰符),Package
newInstance//由构造器Constructer或Class对象调用返回相应类的对象
invoke(方法,方法的可变参数);// 由Method对象调用
setAccessable设置true以取消访问权限的检查
Field利用setXXX,getXXX方法反射读写值,如果是对象直接set,get
反射生成JDK动态代理// by zjerry 不太明白
- JAVA细节上的特别之处
- Perl的特别之处
- scala的特别之处
- 浏览器上的按钮文字特别小 之解决办法
- Java语法上的一些细节
- 一些Java编程上的小细节
- 字符指针的特别之处
- 苍蝇眼睛的特别之处
- 数字101的特别之处
- Ruby语言的特别之处
- 苍蝇眼睛的特别之处
- 函数的几个特别之处
- NSString的length方法特别之处
- LightGBM算法的特别之处
- java 的特别关键字
- const特别之处
- constructor的细节之处
- 细节上的死胡同
- MyEclipse中解决jsp页面中文乱码
- 转载:50国内外最优秀的C/C++源代码网站分享
- Flume-ng的HdfsSink出现Lease mismatch错误
- 语音增强简介
- Xcode Lua语法高亮
- JAVA细节上的特别之处
- Opencv及Kinect/OpenNI常用学习网址
- 泛泰A860版本的识别
- Java与模型驱动架构(MDA)
- 写了个NSObject的扩展类
- 专家:用IPAD看动画片比看电视伤眼十倍
- 【总结】修复Ubuntu和Win7双系统菜单Grub2
- MFC中,怎样在一个特定的控件里画图
- 软件经济学二:用软件经济学的观点来定义问题