Java知识整理
概念问题面向对象和面向过程Java和C++Java 语言特点JDK 和 JRE和JVMOracle JDK 和 OpenJDK字符型常量和字符串常量构造器 Constructor 是否可被 overrideoverride重写和overload重载面向对象三大特性: 封装 继承 多态String 、 StringBuffer 和 StringBuilder自动装箱与拆箱定义一个不做事且没有参数的构造方法的作用java和javax:javax包成为标准一部分接口和抽象类基本与包装类型使用标准自动装箱equlas注意事项成员变量与局部变量== 与 e 与 equals线程、程序、进程线程基本状态final关键字异常处理Throwable类常用方法字段不希望序列化获取用键盘输入内部类staicI/O流BIO、NIO、AIO浅拷贝和深拷贝Collection排序操作查找、替换Arrays操作BigDecimal的用处Arrays.asList使用正确将数组转化为ArrayList简单方法java8的steam不要在 foreach 循环里进行元素的 remove/add 操作Collection.toArray转为数组泛型限定泛型数组(重点)可重入/不可重入锁乐观锁、悲观锁
概念问题
面向对象和面向过程
Java和C++
Java 语言特点
JDK 和 JRE和JVM
Oracle JDK 和 OpenJDK
字符型常量和字符串常量
构造器 Constructor 是否可被 override
override重写和overload重载
面向对象三大特性: 封装 继承 多态
String 、 StringBuffer 和 StringBuilder
自动装箱与拆箱
定义一个不做事且没有参数的构造方法的作用
java和javax:javax包成为标准一部分
接口和抽象类
方法:接口默认public,不可实现;抽象类可有非抽象方法变量:接口只能有static和final一个类可多接口,单抽象类理念:抽象类是模板;接口是行为抽象。
public interface DoSomething {
static String name
="null";
final String type
="animal type";
String
getAnimalName();
}
public interface EatSomething {
String
eat();
}
public abstract class Animal {
abstract public String
getName();
public String
getType(){
return "not a human";
}
}
public class Dog extends Animal implements DoSomething,EatSomething
{
@Override
public String
getName() {
return null
;
}
@Override
public String
getAnimalName() {
return null
;
}
@Override
public String
eat() {
return null
;
}
}
JDK8中,接口可定义静态方法。
public interface EatSomething {
String
eat();
static String
getPlaceName() {
return "house";
}
}
基本与包装类型使用标准
POJO类必须使用包装数据类型。RPC方法返回值和参数必须使用包装类型。局部变量使用基本数据类型。
NPE问题:Null Pointer Exception空指针例外。Integer的null和0表示不同意思,而int没有null,就无法区分意思。
自动装箱
自动装箱创建Integer对象,数值在-128~127,将创建的Integer缓存起来,下次再出现该数值,直接从缓存去对象。
(IDEA阿里巴巴的p3c插件会检测==错误)。
int x
=3;
int y
=3;
System
.out
.println("x==y:"+(x
==y
));
Integer x1
=new Integer(3);
Integer y1
=new Integer(3);
System
.out
.println("x1==y1:"+(x1
==y1
));
System
.out
.println("x1.equals(y1):"+(x1
.equals(y1
)));
上面x和y引用的是相同的对象。
equlas注意事项
jdk7引入Objects.equals(…,…)更好地避免equals调用出错。
成员变量与局部变量
== 与 equals
public class Test {
public static void main(String
[] args
) {
String s
= new String("nihao");
String s1
= new String("nihao");
System
.out
.println("s==s1:"+(s
==s1
));
System
.out
.println("s.equals(s1):"+(s
.equals(s1
)));
}
}
结果:

特殊情况:常量池的作用
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
String aa
="ab";
String bb
="ab";
System
.out
.println("aa==bb:"+(aa
==bb
));
System
.out
.println("aa.equals(bb):"+(aa
.equals(bb
)));
结果:

hashCode 与 equals
String s
= new String("nihao");
String s1
=new String("nihao");
System
.out
.println("s:"+s
);
System
.out
.println("s1:"+s1
);
System
.out
.println("s.equals(s1):"+(s
.equals(s1
)));
System
.out
.println("s.hashcode:"+s
.hashCode());
System
.out
.println("s1.hashcode:"+s1
.hashCode());
结果:

重点注意: equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。
如果hashcode相同,则比较equals。
线程、程序、进程
线程基本状态
final关键字
变量方法(方法锁定,以防任何继承类修改它的含义;第二个原因是效率)。类(类不能被继承)
异常处理

Error(错误):是程序无法处理的错误。Exception(异常):是程序本身可以处理的异。注意:异常和错误的区别:异常能被程序本身处理,错误是无法处理。
Throwable类常用方法
public class MyThrowable extends Throwable {
//返回异常发生时的简要描述
@Override
public String
getMessage() {
return "wait,这里可能出现了问题";
}
//返回异常发生时的详细信息
@Override
public String
toString() {
return "我的异常类";
}
//返回异常对象的本地化信息。
// 使用Throwable的子类覆盖这个方法,可以生成本地化信息。
// 如果子类没有覆盖该方法,则该方法返回的信息与getMessage()
// 返回的结果相同
@Override
public String
getLocalizedMessage() {
return this.getMessage();
}
//在控制台上打印Throwable对象封装的异常信息
@Override
public void printStackTrace() {
super.printStackTrace();
}
}
public static void main(String
[] args
) {
try{
throw new MyThrowable();
}catch (MyThrowable myThrowable
){
myThrowable
.printStackTrace();
System
.out
.println("-----------------------");
System
.out
.println(myThrowable
.getMessage());
System
.out
.println(myThrowable
.toString());
}
}
结果:

try:其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。catch:用于处理try捕获到的异常finally:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return 语句时,finally语句块将在方法返回之前被执行。
catch (MyThrowable myThrowable
){
....
return;
}
finally {
System
.out
.println("你必须执行我finally不可");
}
结果为:

字段不希望序列化
transient关键字,阻止实例中那些用此关键字修饰的的变量序列化;
获取用键盘输入
两种方式
Scanner scanner
= new Scanner(System
.in
);
String s
= scanner
.nextLine();
System
.out
.println(s
);
BufferedReader reader
= new BufferedReader(new InputStreamReader(System
.in
));
String s1
= reader
.readLine();
System
.out
.println(s1
);
内部类
成员内部类
//静态内部类
Circle
.Draw draw
= new Circle.Draw();
//非静态内部类
Circle circle
= new Circle(1);
Circle
.Made made
= circle
.new Made();
局部内部类静态内部类匿名内部类scan_bt
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v
) {
}});
history_bt
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v
) {}});
与以上匿名内部类相同的作用代码为:
private void setListener()
{
scan_bt
.setOnClickListener(new Listener1());
history_bt
.setOnClickListener(new Listener2());
}
class Listener1 implements View.OnClickListener{
@Override
public void onClick(View v
) {
// TODO Auto-generated method stub
}
}
class Listener2 implements View.OnClickListener{
@Override
public void onClick(View v
) {
// TODO Auto-generated method stub
}
}
staic
变量、方法静态代码块:静态代码块—>非静态代码块—>构造方法。静态内部类静态导包(1.5新特性)静态代码块和非静态代码块
public class Dog {
{
System
.out
.println("这里是非静态代码块");
}
static {
System
.out
.println("这里是静态代码块");
}
public Dog(){
System
.out
.println("这里是构造函数");
}
}
结果为:

I/O流
基类:
InputStream/Reader: 所有的输入流的基类
OutputStream/Writer: 所有输出流的基类
BIO、NIO、AIO
BIO: 阻塞IONIO: 同步非阻塞IOAIO: 异步非阻塞的IO
浅拷贝和深拷贝
Collection
排序查找、替换同步控制(可以用JUC包并发集合替代)排序操作
public class Test {
public static void main(String
[] args
) {
ArrayList
list
= new ArrayList();
list
.add(4);
list
.add(3);
list
.add(2);
list
.add(1);
System
.out
.println("开始序列:"+list
);
Collections
.reverse(list
);
System
.out
.println("翻转后:"+list
);
Collections
.shuffle(list
);
System
.out
.println("随机后:"+list
);
Collections
.sort(list
);
System
.out
.println("排序后:"+list
);
Collections
.swap(list
,0,3);
System
.out
.println("交换第1和3个后:"+list
);
//定制sort
Collections
.sort(list
, new Comparator() {
@Override
public int compare(Integer o1
, Integer o2
) {
return -o1
.compareTo(o2
);
}
});
System
.out
.println("定制sort后:"+list
);
}
查找、替换
System
.out
.println(list
+" 二分查找3:"+Collections
.binarySearch(list
,3));
System
.out
.println("最大元素:"+Collections
.max(list
));
System
.out
.println("3出现次数:"+Collections
.frequency(list
,3));
ArrayList
list1
= new ArrayList();
list1
.add(3);
list1
.add(2);
System
.out
.println("3,2出现在哪里:"+Collections
.indexOfSubList(list
,list1
));
结果为:

Arrays操作
int arr
[]={5,4,3,2,1};
Arrays
.sort(arr
,1,3);
System
.out
.println("arr排序1到3:"+Arrays
.toString(arr
));
Arrays
.sort(arr
);
System
.out
.println("arr排序后:"+Arrays
.toString(arr
));
System
.out
.println(Arrays
.toString(arr
));
System
.out
.println("4在位置:"+Arrays
.binarySearch(arr
,4));
结果为:

剩下还有:
比较 equals填充 fill转列表 asList转字符串 toString复制 copyOf
BigDecimal的用处
浮点数之间等值判断不能使用==来比较,包装数据类型不能用equals来比较。
BigDecimal a
= new BigDecimal("1.0");
BigDecimal b
= new BigDecimal("0.9");
BigDecimal c
= new BigDecimal("0.8");
BigDecimal x
= a
.subtract(b
);
BigDecimal y
= b
.subtract(c
);
System
.out
.println("两结果之间进行对比:"+x
.equals(y
));
//保留几位小数n
BigDecimal m
= new BigDecimal("1.2223456");
BigDecimal n
= m
.setScale(3, BigDecimal
.ROUND_HALF_DOWN
);
System
.out
.println(m
+"保留三位:"+n
);
结果显示为:

Arrays.asList使用
注意必须传入对象数组,基本类型不可以。
且底层就是数组。
最重要的是,Arrays.asList() 方法返回的并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法。
Integer arrls
[]={8,7,6,5};
List
list
= Arrays
.asList(arrls
);
System
.out
.println("使用asList后:"+list
.toString());
正确将数组转化为ArrayList
简单方法
new ArrayList(Arrays.asList(“a”, “b”, “c”))
java8的steam
不要在 foreach 循环里进行元素的 remove/add 操作
可以用迭代器的remove方法,否则抛出异常。
fail-fast机制: :多线程操作集合,一线程访问集合,但检测到集合被其他线程修改,便会出现情况。java.util包下面的所有的集合类都是fail-fast的,而java.util.concurrent包下面的所有的类都是fail-safe的。
Collection.toArray转为数组
list.toArray(new String[0])
这里只为指定返回的数组的类型。0是为节省空间。
泛型限定
public static T
Min(T
[] nums
){
T val
=nums
[0];
for(int i
=1;i
val
=nums
[i
];
}
}
return val
;
}
其中T extends Number表明上限是Number,也就是T必须是Number的子类。? super T 表明下限是T。
例如Integer是这样定义的:
public final class Integer extends Number implements Comparable
T表示泛型? 表示不确定的类型,一般用在通配
Object表示java中所有类的父类,在集合中使用时要格外注意。jdk为了便于理解,用
K表示键,V表示值,T表示type类型,E表示enum枚举,其实这四个都只是符号,都是表示泛型名称。换成其他字母都没关系,但是都要在之前声明。
泛型数组(重点)
可重入/不可重入锁
不可重入:线程获取锁,再次获取锁时,就会被阻塞。可重入: 线程可以进入已经拥有锁的同步代码块。isLockedfalselockedBynulllockedCount0
进入lock():
thread为当前线程。
由于while(isLocked && lockedBy != thread),而isLocked为false,所以不执行while内的wait,而是
isLockedtruelockedBy当前线程lockedCount1
接着这个线程再次申请这个锁,由于满足lockedBy与当前线程匹配,所以仍不能执行while,而是
isLockedtruelockedBy当前线程lockedCount2
如果此时有其它线程执行lock(),那么就会满足while的条件,而执行wait(),挂起等待。
总结:如此便实现了一个线程可以重入一个锁。
乐观锁、悲观锁
synchronized是悲观锁,这种线程一旦得到锁,其他需要锁的线程就挂起。CAS是乐观锁,每次不加锁,有冲突就重试。
CAS( Compare And Swap )比较并替换。