JavaSE
1、constructor(构造方法)在一个对象被new时执行,constructor可以省略(系统提供),一个类可以定义多个constructor(重载),一个类的构造器可以调用这个类中的其他构造器,注意this
和super
;java构造方法可以有任何访问的修饰: public, protected, private 或者没有修饰(通常被 package 和 friendly 调用) ,但是 不能有以下非访问性质的修饰: abstract, final, native, static, 或synchronized、super
可以用来访问父类被隐藏的非私有成员变量、用来调用父类中被重写的方法、用来调用父类的构造函数
new一个对象的方式:
(1)用new语句创建对象,这是最常用的创建对象的方式。
(2)运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3)调用对象的clone()方法。
(4)运用**反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法.
类方法中的相关调用
(1)在类方法中调用本类的类方法时可直接调用
(2)在类方法中可用this
来调用本类的类方法
(3)在类方法中不只能调用本类中的类方法,还能调用实例方法(类比main方法,创建对象之后调用)
先要理解什么是类的方法,所谓类的方法就是指类中用static 修饰的方法(非static 为实例方法),
2、object 是引用数据类型,只声明而不创建实例,只会在栈内存中开辟空间,默认为空,空占1 bit.
3、类型为Final的类,即不能被其他类继承的类:StringBuffer,String
,且String中的值是不可变的,StringBuffer运行速度比Strin快。
不是最终类:
HashMap
,Hashtable
不是最终类,可以被其他类继承;
Thread
可以被继承,用于创建新的线程;Number
类可以被继承,Integer,Float,Double等都继承自Number类;ClassLoader
可以被继承,用户可以自定义类加载器;
4、数组是一个对象,不同类型的数组具有不同的类,数组是一个连续的存储结构,长度是不可变的;两个数组用equals方法比较时,会逐个遍历其中的元素,对每个元素进行比较;数组可以是二维数组,且可以有多维数组,都是在Java中合法的。
5、final修饰的方法只是不能重写,可以进行重载,final 的成员方法除了能读取类的成员变量,还能读取类变量;static修饰的方法只能访问类的成员变量;final与abstract
不能同时出现。final不能修饰抽象类和接口(不让人家继承和实现了?)
6、标识符
Java 中标识符是为方法、变量或其他用户定义项所定义的名称。标识符可以有一个或多个字符。在 Java 语言中,标识符的构成规则如下。
-
标识符由数字(0-9)和字母(A~Z 和 a~z)、美元符号($)、下划线(_)以及 Unicode 字符集中符号大于 0xC0 的所有符号组合构成(各符号之间没有空格)。
-
标识符的第一个符号为字母、下划线和美元符号,后面可以是任何字母、数字、美元符号或下划线。
另外,Java 区分大小写,因此 myvar 和 MyVar 是两个不同的标识符。
提示:标识符命名时,切记不能以数字开头,也不能使用任何 Java 关键字作为标识符,而且不能赋予标识符任何标准的方法名。
标识符分为两类,分别为关键字和用户自定义标识符。
-
关键字是有特殊含义的标识符,如 true、false 表示逻辑的真假。
-
用户自定义标识符是由用户按标识符构成规则生成的非保留字的标识符,如 abc 就是一个标识符。
提示:使用标识符时一定要注意,或者使用关键字,或者使用自定义的非关键字标识符。此外,标识符可以包含关键字,但不能与关键字重名。
例如以下合法与不合法标识符。
- s合法标识符:
date、$2011、_date、D_$date
等。 - 不合法的标识符:
123.com、2com、for、if
等。
标识符用来命名常量、变量、类和类的对象等。因此,一个良好的编程习惯要求命名标识符时,应赋予它一个有意义或有用途的名字。
7、Java与C语言很大的一点区别就是java是不需要使用者关注内存分配以及管理的,Java中没有指针机制;Java的垃圾回收不是程序结束
后立即回收。
8、各种运算符:
~按位取反 -num-1
^按位异或 相同是0,不同是1,例如14^3 14转化成二进制是1100,3转换成二进制是0011 按位异或 最后得到13
\>>右移 \>>>无符号右移 <<左移 >>是算术右移操作符 >>>是逻辑右移操作符
-
instanceof :用来判断某个实例变量是否属于某种类的类型,但是实例变量可以放置在前面也可以放置在后面
-
"?:": 三目运算符
-
&: 逻辑与,按位与 |按位或
-
&&: 逻辑运算:
9、基本数据类型越界问题:
byte b = (byte) 129;
//-128~127 当b=128的时候,会跳到最小的-128,所以c的值是-128,b的值是-127
byte c = (byte) 128;
//switch :
switch语句判断条件可以接受的数据类型
switch括号里面只能放int类型,char,byte和short类型会被编译成int,其中char类型比较特殊,例如’1’会被编译成49。
10、IO流:使用ObjectOutputStream
和ObjectInputStream
可以将对象进行传输.声明为static和transient类型的成员数据不能被串行化。因为static代表类的状态, transient代表对象的临时数据。对象序列化的所属类需要实现Serializable
接口
IO流 读写锁
CopyOnWriteArrayList
适用于写少读多的并发场景
ReadWriteLock
即为读写锁,他要求写与写之间互斥,读与写之间互斥, 读与读之间可以并发执行。在读多写少的情况下可以提高 效率
ConcurrentHashMap
是同步的HashMap
,读写都加锁
volatile
只保证多线程操作的可见性,不保证原子性 ,不能保证线程安全
11、继承:Java只支持单继承,实现多重继承三种方式:
(1)直接实现多个接口 (2)扩展(extends)一个类然后实现一个或多个接口 (3)通过内部类去继承其他类
1.类与类之间的关系为继承,只能单继承,但可以多层继承。
2.类与接口之间的关系为实现,既可以单实现,也可以多实现。
3.接口与接口之间的关系为继承,既可以单继承,也可以多继承。
子类与父类:子类能继承父类的所有成员(有点反常,但是可以通过反射实现)
12、接口冷知识:java中接口只能使用public修饰,接口内方法默认为public abstract;接口只能继承接口,可以单继承,多继承;接口只能用public修饰,常量与方法声明如下:所以接口的子类,重写方法后,修饰符也为public,不能修改
13、抽象类: abstract类只能用来派生子类,不能用来创建abstract类的对象。即不能常规的new一个对象、抽象类和接口都不能被实例 化(忽略匿名内部类)
14、集合相关:ArrayLIst,LinkedList实现自List接口
,AbstractSet实现自Set接口
,HashSet继承自AbstractSet
,同时也实现了Set
;
HashSet子类依靠hashCode(),``equals()
方法区分重复元素。
Vector
与ArrayList
一样,也是通过数组实现的,不同的是Vector支持线程的同步,但是效率比较低。volatile
关键字也是不能保证线程安全的; 但是JAVA的变量声明方式可以避免程序在多线程竞争情况下读到不正确的值==》volatile
或者static
volatile
修饰 volatile–>有序性、可见性 Stack也是线程安全的类
15、对比
Hashtable:
(1)Hashtable 是一个散列表,它存储的内容是键值对(key-value)映射。继承自Dictionary
类。并实现了Set
接口
(2)Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。
(3)HashTable直接使用对象的hashCode。
HashMap:
(1)继承自AbstractMap
类,实现了Map
接口,由数组+链表组成的,基于哈希表的Map实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。
(2)不是线程安全的,HashMap可以接受为null的键(key)和值(value)。
(4)当有重复的键对应新的值时,将会产生替换
(4)HashMap重新计算hash值
(5)用链地址法来解决哈希冲突的
线程安全的map:
HashTable,SynchronizedMap,ConcurrentHashMap
16、JVM垃圾回收机制:
java提供了一个系统级的线程,即垃圾回收器线程。用来对每一个分配出去的内存空间进行跟踪。当
JVM空闲时,自动回收每块可能被回收的内存,[GC是完全自动的,不能被强制执行] ,程序员最多只能
用System.gc()来建议执行垃圾回收器回收内存,但是具体的回收时间,是不可知的。当对象的引用变
量被赋值为null,可能被当成垃圾。 垃圾回收在jvm中优先级相当相当低
垃圾回收机制只是回收不再使用的JVM内存,如果程序有严重BUG,照样内存溢出
进入DEAD的线程,它还可以恢复,GC不会回收
17、JVM相关
java程序内存泄露的最直接表现是: 程序抛内存溢出的Exception
属于JVM规范:方法区,程序计数器、虚拟机栈
18、包装类型Float
- Float是类,float不是类.
- 查看JDK源码就可以发现Byte,Character,Short,Integer,Long,Float,Double,Boolean都在
java.lang
包中. - Float正确的赋值方式是Float f=1.0f,若不加f会被识别成double型,double无法向float隐式转换.
- Float a= new Float(1.0)是正确的赋值方法,但是在1.5及以上版本引入自动装箱拆箱后,会提示这是不必要的装箱的警告,通常直接使用Float f=1.0f.
19、Object类中的方法
20、注意静态方法和类方法的区别:
类方法: 一般用static修饰,属于类自己的方法,会加载,类的成员变量会被默认初始化 ;在静态方法中不可用this来调用本类的类方法;在静态方法中调用本类的静态方法时可直接调用;在静态方法中绝对不能直接调用实例方法。使用【new 类名().实例方法名】可以间接调用。
实例方法:是除了类方法以外的方法,一般需要通过对象调用,注意区分
21、多线程
1.start方法
用 start方法来启动线程,是真正实现了多线程, 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。但要注意的是,此时无需等待run()方法执行完毕,即可继续执行下面的代码。所以run()方法并没有实现多线程。
2.run方法
run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码
22、运算符的优先级
23、基本认知
java的基本编程单元是类,基本存储单元是变量。
//基本(简单)数据类型是包装类的简写形式,可以用包装类替代基本(简单)数据类型(X)
//long和double都占了64位(64bit)的存储空间。8个字节
//默认的整数数据类型是int,默认的浮点数据类型是double
//和包装类不同,基本(简单)数据类型声明的变量中没有静态方法,用来完成进制转化等。
多态的作用:隐藏细节、提高可重用性、扩展代码模块 针对一消息,不同的对象可以以适合自身的方式加以响应
异常代码块 :try catch ,catch可以省略
try-catch
try-finally
try-catch-finally
但catch和finally语句不能同时省略!
24、switch(x),其中x允许的数据类型
jdk1.7之前byte,short ,int ,char jdk1.7之后加入String
24、八大数据类型
25、异常
JavaWeb
1、Java数据库连接库JDBC用到哪种设计模式?==》桥接模式。将抽象部分与它的实现部分分离,使它们都可以独立地变化。将抽象与实现解耦。JDBC连接 数据库 的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不动,原因就是JDBC提供了统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了
2、servlet
在多线程下其本身并不是线程安全的。
如果在类中定义成员变量,而在service中根据不同的线程对该成员变量进行更改,那么在并发的时候就会引起错误。最好是在方法中,定义局部变量,而不是类变量或者对象的成员变量。由于方法中的局部变量是在栈中,彼此各自都拥有独立的运行空间而不会互相干扰,因此才做到线程安全。
3、四大域对象之一的application:application对象:1个application对象实现了用户间数据的共享,可存放全局变量
session对象
:session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止
request对象
:客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应