我的java基础学习易错点和易忘点总结(一)

一.继承

A:子类只能继承父类所有非私有的成员(成员方法和成员变量)
B:子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。

二.继承中构造方法的关系

	A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
	B:为什么呢?
		因为子类会继承父类中的数据,可能还会使用父类的数据。
		所以,子类初始化之前,一定要先完成父类数据的初始化。
		
		注意:子类每一个构造方法的第一条语句默认都是:super();

三.重载和重写

方法重写:子类中出现了和父类中方法声明一模一样的方法。
方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值无关。

四.代码块

一个类的静态代码块,构造代码块,构造方法的执行流程:
	静态代码块(一次) > 构造代码块(构造一次走一次) > 构造方法(调用一次走一次)

五.多态

多态中的成员访问特点:
	A:成员变量
		编译看左边,运行看左边。
	B:构造方法
		创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
	C:成员方法
		编译看左边,运行看右边。
	D:静态方法
		编译看左边,运行看左边。
		(静态和类相关,算不上重写,所以,访问还是左边的)
		
	**成员变量仅仅是该事物的外在(父类)特征描述,而成员方法是该事物的内在(子类)功能描述**
	**由于成员方法存在方法重写,所以它运行看右边。**
	
	巧妙理解:
		父亲雇了儿子去干活,(多态方式创建对象)
		要用的工具和资源是父亲的,(工具和资源表示父类的成员变量,所以访问成员变量时是访问的父类成员变量)
		干什么活是父亲决定的,(干活表示成员方法,子类新增的成员方法父类不可以访问)
		而干活方式是儿子自己的,与父亲的方式无关,(干活指成员方法,子类重写了父类的成员方法,所以运行看子类的成员方法)

六.接口

成员变量;只能是常量,并且是静态的。
		常量:1.因为接口是不能实例化的也就是不能被初始化,所以必须是常量
		2.不能实例化,所有实现类都共有一份,避免别的实现类修改这个值
		静态:1.接口没有对象,所以要用类名来访问,那就是静态喽;当多实现时同名的变量名也避免了歧义
		2.不能实例化,所有实现类都共有一份
			默认修饰符:public static final
			建议:自己手动给出。
	构造方法:接口没有构造方法。(不能实例化)
	成员方法:只能是抽象方法。
			默认修饰符:public abstract
			建议:自己手动给出。

七.抽象类和接口的区别:

A:成员区别
	抽象类:
		成员变量:可以变量,也可以常量
		构造方法:有
		成员方法:可以抽象,也可以非抽象
	接口:
		成员变量:只可以常量
		构造方法:无
		成员方法:只可以抽象
B:关系区别
	类与类
		继承,单继承
	类与接口
		实现,单实现,多实现
	接口与接口
		继承,单继承,多继承	
C:设计理念区别
	抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
	接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。

	抽象的概念是将不可变的提取出来封装到一起,将可变的东西放到现实中去。
	接口的设计理念是高层抽象,全部不可变。

八.toString

 * public String toString():返回该对象的字符串表示。
 * this.toString() = this.getClass().getName()+'@'+Integer.toHexString(this.hashCode());
 * 例如:cn.itcast_02.Student@42552c

九.异常

1:如果catch里面有return语句,请问finally里面的代码还会执行吗?
	如果会,请问是在return前,还是return后。
	会。前。准确的说,应该是在中间。
2.throw是业务型异常。throws是方法声明异常。try是捕获异常。
3:try...catch...finally的格式变形
	A:try...catch...finally
	B:try...catch
	C:try...catch...catch...
	D:try...catch...catch...finally
	E:try...finally
		这种做法的目前是为了释放资源。
4. 异常注意事项:
	A:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
	B:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
	C:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

十.String

1.不可变性:改变其值时,只是改变了字符串常量池中的指向,实际的值是没有变化的。
2. 前者创建一个对象,后者创建两个对象
    	new String会现在常量池中查看有没有这个字符串长量,有的话复制到堆内存中,没有就在常量池中创建并复制堆内存
   	3. 字符串如果是变量相加:先开空间在拼接
    	字符串如果常量相加:是先加在常量池里找,如果有就直接返回,没有就创建

十一.常用类

1.StringBuffer:线程安全的可变字符串、StringBuilder:线程不安全的可变字符串
2. * int -- String:String.valueOf(number)* String -- int:Integer.parseInt(s)
3.Math:int number = (int) (Math.random() * (end - start + 1)) + start;//生成一个在任意范围的随机数
4.Random类:
	public Random():没有给种子,用的是默认种子,是当前时间的毫秒值
	public Random(long seed):给出指定的种子,给定种子后,每次得到的随机数是相同的。
	public int nextInt():返回的是int范围内的随机数
	public int nextInt(int n):返回的是[0,n)范围的内随机数

十二.泛型和集合类

1.泛型使用:
	1.泛型定义在类名上:public class ObjectTool<T> {}
	2.泛型定义在方法上:public <T> void show(T t) {}
	3.泛型定义在接口上:public interface Inter<T> {}	public class InterImpl<T> implements Inter<T> {}
	4.通配符:
		* ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了:<?> 
		* ? extends E:向下限定,E及其子类:<? extends Animal> 
		* ? super E:向上限定,E极其父类:<? super Animal>
2.ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。 
	产生的原因:
	迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
	其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。
	解决办法:
	A:迭代器迭代元素,迭代器修改元素
		元素是跟在刚才迭代的元素后面的。
	B:集合遍历元素,集合修改元素(普通for)
		元素在最后添加的。
3. JDK5的新特性:自动拆装箱,泛型,增强for,静态导入,可变参数,枚举
4.List集合的排序方式:
	Collections提供两种排序方法:
	1.Collections.sort(List<T> list);
	  此方法需要泛型T这个Bean实现Comparable<T>接口,并且实现compareTo()方法排序;
	2.Collections.sort(List<T> list, Comparator<? super T> c);
		此方法,在泛型T这个Bean没有实现Comparable<T>接口的时候,多个一个参数,是一个接口我们需要实现其compare()方法排序;
5.HashSet:存储字符串并遍历--问题:为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
 * 通过查看add方法的源码,我们知道这个方法底层依赖 两个方法:hashCode()equals()* 步骤:
 * 		首先比较哈希值(重写后哈希值是通过属性计算出来的和属性有关)
 * 		如果相同,继续走,比较地址值或者走equals()
 * 		如果不同,就直接添加到集合中
 * 按照方法的步骤来说:
 * 		先看hashCode()值是否相同
 * 			相同:继续走equals()方法
 * 				返回true:	说明元素重复,就不添加
 * 				返回false:说明元素不重复,就添加到集合
 * 			不同:就直接把元素添加到集合
 * 如果类没有重写这两个方法,默认使用的Object()。一般来说不同相同。
 * 而String类重写了hashCode()equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。
 注意:
	1.equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
    2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
	所有对于需要大量并且快速的对比的话如果都用equal()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),如果hashCode()相同,此时再对比他们的equal(),如果equal()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!
	3.当自定义类没有重写hashCode和equals方法时,默认走的是Object的hashCode和equals方法,这时他的hashCode的值是不一样的。
	
6.TreeSet排序方式:
	A:自然排序(元素具备比较性)
		让元素所属的类实现自然排序接口 Comparable
	B:比较器排序(集合具备比较性)
		让集合的构造方法接收一个比较器接口的子类对象 Comparator

你可能感兴趣的:(java学习)