1、static方法修饰的变量,只在内存中占一个内存地址,可以多个实例公用,可以改变值。final字段修饰的变量,一旦赋值后不可更改。
static修饰的方法,只能使用静态方法和静态变量,如果要使用实例化的方法,就需要新建一个引用。
public class main {
public static void main(String[] args) {
main main = new main();
main.getStsss();
}
private String getStsss(){
System.out.println("something");
return "something";
}
}
2、重写是重写父类方法,重载是同一个方法不同参数。
3、注意枚举类型,可以认为枚举类型中,每一个变量都是一个实例,都可以在声明的时候调用构造函数。
public enum Day {
FIREWALL("1"),
SECRET("2"),
BALANCE("3");
private String typeName;
Day(String typeName) {
this.typeName = typeName;
}
public String getTypeName(){
return typeName;
}
}
public static void main(String[] args) {
System.out.println(Day.BALANCE.getTypeName());
}
4、协变: 继承的方法,本来应该返回父亲类型的,现在返回子类型,比如object的克隆方法,重写这个方法,可以返回自己的类型,不用返回object。
5、继承中,实例方法是重写,静态方法是隐藏。
6、this就想到于当前类。super就是父类。
7、父类的构造器必须包含所有的子类构造器,只能多或者等于,不能少。调用子类构造器的时候,必须调用父类构造器,如果子类不写,默认调用父类参数为空的构造器,如果父类没有参数为空的构造器,那么报错。
8、instanceof Java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
9、哈希
10、接口中可以定义常量,常量默认为static final public,接口中的方法默认都是public abstract。
11、泛型,只在编译的时候会校验,运行时候会直接替换类型。
12、泛型和object的区别,泛型声明:
public class Fruit<T> {
private T key;
public void setT(T t) {
key = t;
}
public T getT() {
return key;
}
}
泛型声明了引用以后,这个泛型和普通类型在运行时候一模一样,这和object有本质区别,object是利用继承机制,强制类型转换来实现这一点的。
13、一个类文件中可以声明多个类或者接口,但只能有一个是public。
14、Set——不能包含重复元素的集合。List——一个有序的集合。队列——是一个其元素带有先后处理顺序的集合。
15、关于java中泛型的通配符‘?’,我理解的:通配符和泛型的功能一样,一旦传入某个参数,这个?就被定死一个类型,只不过,他和泛型方法的区别在于泛型方法每定义一个E,Z,T都要写到方法前面,但‘?’通配符随时可用。详情参看:https://blog.youkuaiyun.com/s10461/article/details/53941091
public void showKeyValue1(Generic<?> obj){
Log.d("泛型测试","key value is " + obj.getKey());
}
16、set集合,使用迭代器迭代。
Set<Integer> set = new HashSet<Integer>();
Iterator i = set.iterator();
while (i.hasNext()){
System.out.println(i.next());
}
17、set有三种
HashSet:效率高,但是顺序不定。
TreeSet :TreeSet,将其元素存储在一个红黑树中,按元素的值顺序排列;
LinkedHashSet是作为一个哈希表实现的,用链表连接这些元素,按元素的插入顺序排列。
18、List有两种:ArrayList, LinkedList
集合之间的复制,有一个很厉害的技术:
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
List<String> list2 = new ArrayList<>(list);
这样可以得到一个list集合的复制,list2有单独的内存空间。
注意:set 和list都有这种操作,可以查看源码。
19、java中的克隆,是一定要继承clone接口的,然后再调用Object类中的clone方法,其实Cloneable接口仅仅是一个标志,而且这个标志也仅仅是针对 Object类中 clone()方法的,如果 clone 类没有实现 Cloneable 接口,并调用了 Object 的 clone() 方法(也就是调用了 super.Clone() 方法),那么Object 的 clone() 方法就会抛出 CloneNotSupportedException 异常。
http://www.cnblogs.com/gw811/archive/2012/10/07/2712252.html
public Son clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
if (o instanceof Son)
return (Son) o;
else
return null;
}
浅层复制与深层复制概念:
浅层复制: 被复制的对象的所有成员属性都有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅层复制仅仅复制所考虑的对象,而不复制它所引用的对象。(概念不好理解,请结合下文的示例去理解)
深层复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不是原有的那些被引用的对象。换言之,深层复制要复制的对象引用的对象都复制一遍。
20、list,set中的equal是比较他们中每一个值的大小,重写过equal方法。
21、Map:HashMap TreeMap LinkHashMap。
22、 list中 排序原理:本质上是调用list中的compareTo方法。如果每月compareTo方法,则需要新建一个构造器0。详情参见:https://blog.youkuaiyun.com/veryisjava/article/details/51675036
23、java中string的比较方法,默认的是先比较第一个字符的ascii码,如果第一个字符相等了,再比较第二个字符。
24、新建一个线程,可以实现Runnable接口,也可以继承Thread接口,本质都是重写run方法。启动方式:
public class RunnableDemo implements Runnable {
public void run() { //实现Runnable接口,则必须实现该接口中的run方法
System.out.println("这是一个线程!");
}
public static void main(String[] args) {
(new Thread(new RunnableDemo())).start();
}
}
25、通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;而通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为Eden、Survivor(又可分为From Survivor和To Survivor)、Tenured;方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在常量池中,常量池是方法区的一部分,。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError。