JDK(Java Developer's Kit): Java开发人员工具包。
抽象类:用abstract修饰的类,抽象类不能被实例化,即不能new成一个对象。
抽象方法:abstract修饰的方法。仅有方法申明,而没有方法体的方法(没有{},若有{}但里面是空的,这也算实现了,叫做空实现)。 抽象类中并不一定要全是抽象方法,也可以写实现方法。
或者可以说:包含抽象方法的类就叫抽象类。如果一个类中包含一个或多个抽象方法,那这个类就是抽象类。
接口(interface):一种特殊的抽象类,所有方法都是抽象的。 定义类的规范, 实现该接口的类便要遵守接口所定的规则。 接口中定义的的变量必须初始化,默认类型为public static final(也就是常量了),接口中的方法都是抽象方法,默认类型为public abstract。
接口可以继承另一个接口,但接口不能实现另一个接口。 一个类可以实现多个接口,但只能继承一个类。(多实现,单继承)
接口和抽象类的区别:接口是特殊的抽象类,抽象类中的方法并不一定全是抽象方法,而接口中的方法一定得是抽象的。 接口不可以实例化。
抽象类和接口的异同:
都是一种抽象的约束,或者说规范。
都不能实例化。
里面都可以放抽象方法。不过接口要求必须全是抽象方法。
抽象类的本质是类,它只能被单继承;而接口可以被多实现(一个类可以实现多个接口)
switch(integral-selector) { case integral-value1 : statement1; break; case integral-value2 : statement2; break; case integral-value3 : statement3; break; .... default : statemet; }
多态:
父类型的引用可以指向子类型的对象。例如: People stu = new Student();
多态是一种运行期行为,不是编译期行为。
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的该同名方法。
向上转型:Student当然也是People类型的,(乌鸦一定是鸟类,动物,生物) People stu = new Student();
向下转型:(要强制类型转换) People stu = new Student(); Student stu1 = (Student)stu;
final : 终态。表示固定的形态,不能被修改扩展。
当它修饰类时,表示该类不能被继承拓展; 修饰方法时,表示该方法不能被子类中的方法覆盖(重写); 修饰变量时,表示常量。
static关键字:
一般情况下在一个类中,每创建一个对象Java就会在内存中为每个对象单独分配一块存储空间,该空间内有该对象特有的字段值和方法;
但是如果字段或方法前有static关键字,则表示该字段和方法是属于整个类公有的,Java会分配一块“公共区域”来存储这些字段和方法。
因此可以直接通过类调用这些方法:XXXClass.xxxMethod();
static方法中不能调用非静态方法!!!为什么?理解不了。。。。
return关键字的作用:
1.表示方法已经结束,退出此方法;
2.如果此方法产生了一个值,则将它带出方法,传递出去。
如果方法返回类型为void,则程序员不必手写return,因为其实在该方法的结尾处有个隐藏的return null。此时return的作用只是退出此方法。
String类 :
String是常量,其对象一旦创建就不能被改变。那些看起来会修改String值的方法,其实都是创建了一个全新的String。
String通过+可以拼接其他东西,并默默地把人家的数据类型转换为String类型,拼接后的String是一个全新的String对象。
字符串里的+表示前后字符串连接,若一个不是字符串,那它会自动被转换为字符串,然后进行字符串连接。
例如: System.out.println("abc"+123);123原本是int型的,但在此会被转换成String,然后连接成新字符串"abc123"。
StringBuffer和String的主要区别就是StringBuffer创建的对象的值可以改变,而String的对象的值一旦创建便不能再变。
String和StringBuffer的相互转换:
需要注意的是String和StringBuffer属于不同的类型,没有继承关系,所以不能强制类型转换。他们之间转换必须如下:
String str1 = "abc";
StringBuffer strbuf1 = new StringBuffer(str); // String类型转换为StringBuffer
StringBuffer strbuf2 = new StringBuffer("def");
String str2 = strbuf2.toString(); // StringBuffer类型钻换为String
字符串对象的两种创建方式:
String str1 = new String("aaa");
String str2 = new String("aaa");
这是两个对象,只要new,就会创建一个对象。
String str1 = "aaa";
String str2 = "aaa";
同一个对象。 具体解释见:http://www.cnblogs.com/mengdd/archive/2013/01/03/2842846.html
数组(Array):相同数据类型的集合。
定义数组的几种方式: int[] array = new int[10]; int array[] = new int[10]; int[] a = {1,2,3,4}; int[] a = new int[]{1,2,3,4};
容器/集合(collection):容器的用途就是保存对象。集合中不能存放基本类型的数据,要存它的包装类的对象,即集合中只能存放对象。
以前,编译器的数据类型是Object,当插入对象时,无论对象的类型是什么都是没问题的,但是当get时,它对所有对象的返回类型都是Object,显然,这样是有问题的。
为了避免出现这样的错误,我们可以用尖括号里规定该集合存储的特定数据类型。List<String>
List<String> lst = new ArrayList<String>();
本来new的是ArrayList类型的对象,但前面的类型却为List,但lst对象运行时他却能调用自己的方法,我们已经知道这便是Java的多态。
但这样写必须满足:lst调用的方法必须是List接口中有的。
它先会从父类或接口中查找调用的方法,若存在,则就会调用子类中覆盖的此方法。若父类中不存在lst调用的方法,则会报错。
List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问。
ArrayList:
ArrayList的底层数据结构是数组,执行查询操作效率较高;如果ArrayList插入或删除一条数据,那么该数据插入点或删除点后的数据都要移动,低效率。
非同步,如果多个线程同时访问一个ArrayList,则需自己同步。
数组和ArrayList的区别: 集合(ArrayList)只能保存对象,而数组既能保存基本类型的数据也能保存对象;数组的大小是固定的,而ArrayList没有固定大小
LinkedList:
LinkedList的底层数据结构是双链表,插入,删除效率很高。
非同步。
Vector:
与ArrayList类似,但Vector是线程同步的。但一般操作效率没ArrayList高。
Set集合是无序集合,集合中的元素不可以重复,访问集合中的元素只能根据元素本身来访问。
HashSet:
HashSet的底层数据结构是HashMap,value的值都是统一的,而HashSet的值是存储在key里的,这也就是Set里元素不能重复的根本原因,因为Map里key不能重复。
LinkedHashSet:HashSet的一个子类,链表。
SortSet(接口):
TreeSet: 把放入集合中的元素按一定顺序排列。加入集合的元素必须是可比较的,不然加第二个元素时就会报错:ClassCastException异常
Map集合中保存(key,value)对形式的元素,key不能重复,若添加已经存在的key,不会报错但会覆盖原来的(key,vlaue),Map的添加方法叫put(K key,V vlaue)。
HashMap:
我们已经知道HashSet的底层数据结构是HashMap。而HashMap的底层数据结构是什么呢?
HashMap的底层维护一个数组,我们向HashMap中所放的对象实际上是存储在该数组中。
当向HashMap中put(key,value)一对键值对时,它会根据key的hashCode值计算出一个位置,位置就是此对象准备往数组中存放的位置。
两种遍历集合的方式:
Iterator:迭代器。首先集合获取一个迭代器,然后迭代器里通常用hasNext(),next()
foreach:
Collection和Collections的区别:
Collection是Java集合的顶级接口,接口List和Set都实现了它。
而Collections是针对于Java集合的帮助类。它提供一系列静态方法对各种集合进行各种操作。
泛型:所谓泛型,就是变量类型的参数化,由程序员指定集合只能容纳的数据类型。
以前,编译器的数据类型是Object,当插入对象时,无论对象的类型是什么都是没问题的,但是当get时,它对所有对象的返回类型都是Object,显然,这样是有问题的。 为了避免出现这样的错误,我们可以用尖括号里规定该集合存储的特定数据类型。List<String>
通过使用泛型,就可以防止在编译器将错误类型的对象放入容器里。
有关泛型博客:http://www.cnblogs.com/mengdd/archive/2013/01/21/2869778.html
包装类 :8种基本数据类型,不是对象。为此Java里定义了8个对应的包装类,他们可以作为对象使用。
自动装箱和自动拆箱:
自动装箱:基本数据类型自动转换为包装类型;
自动拆箱:包装类型自动转换为基本数据类型。
Java的反射机制:
动态的(运行时)获取类的信息以及动态调用对象的方法的功能。
要想使用反射,首先需要获得待操作的类所对应的Class对象。
Java中,无论生成某个类的多少个对象,这些对象都会对应于同一个Class对象。
这个Class对象是由JVM生成的,通过它能够获悉整个类的结构。
获取Class对象常用的三种方法:
1.使用Class类的静态方法: Class.forName("。。。。");
2.使用对象的getClass()方法 : 对象.getClass();
3.使用类的.class语法 : String.class;
Class类 : 每个类在开始运行时,Class类都会通过类加载器生成一个该类的Class对象,里面存储了该类的信息。
Java IO流 :
根据处理数据类型的不同:字节流、字符流。字节流:InputStream,OutputStream 俩抽象类及下的子类。字符流:Reader,Writer 俩抽象类及以下的子类。
根据数据流向不同:输入流、输出流。
字节流和字符流的区别:
读写单位不同:字节流以字节为读写单位,字符流以字符为读写单位,可能是多个字节。
处理对象不同:字节流能处理所有类型的数据(包括图片、avi),字符流只能处理字符类型的数据。只要是处理处文本数据,就优先考虑字符流,除此之外都使用字节流 。
装饰流:
File类:
Java对象序列化:将对象转换成字节流保存起来,并在以后再转换还原成对象,就成为对象序列化;只有实现了Serializable接口的类的对象才能序列化。
对象持久化:把对象保存到永久存储设备上称为持久化。
Java基本数据类型:
Java中有8种基本数据类型:byte, char, short, int, float, long, double, boolean
但基本类型不是对象,所以Java对应的有8个包装类:Byte, Character, Short, Integer, Float, Long, Double, Boolean
1 char = 2 byte 1 short = 2 byte
1 int = 4 byte 1 float = 4 byte
1 long = 8 byte 1 double = 8 byte
1 byte = 8 bit(1字节 = 8位)
基本数据类型自动转换成包装类型叫自动装箱;反之,叫自动拆箱。
高精度数字:用于表示金额等。BigInteger 和 BigDecimal类
操作符:
一元加,减操作符:
自动递增递减:(前缀式和后缀式)
++a :先运算,后生成值;
a++ : 先生成值,后运算。
关系操作符:关系操作符生成的是一个boolean结果。
==和equals()方法的比较:
其实equals()的默认行为是比较引用,若返回true,则表示它们指向同一个地址,即同一个对象。此时,==和equals()作用是一样的。
但如果在自己的类中覆盖了equals()方法,则equals()方法只表示比较两对象的值(内容)是否相等。
逻辑操作符:与(&&),或(||),非(!)。能根据参数的逻辑关系,生成一个boolean值(true/false)。
指数计数法:Java中的e=10,并不是2.718。
按位操作符:
移位操作符:
三元操作符:boolean-exp ? value1 : value2; 它表示如果布尔表达式为真,则执行value1,若为假,则执行value2。
三元操作符的作用其实等价于if...else...语句,但它更简洁高效,不过它可读性差。
数据类型转换:
扩展转换:比如float a = 12;当将int型数据12赋值给float类型的a时,编译器会自动的把12转换成为float型的。这就叫扩展转换,也叫类型提升,类型提升是安全的。
窄化转换:会出现数据装不下而丢失信息的情况,所以窄化转换是不安全的,如果非要转换,则要强制转换。
Java中没有sizeof():
在C和C++中,不同的数据类型在不同的机器上可能有不同的大小,C程序员必须通过sizeof()得知机器为那些数据类型分配的字节数。
而Java不存在这个问题,因为所有数据类型在不同的机器上大小是相同的。
迭代:for循环和foreach()的区别:
break 和 continue的区别:
break: 强行退出循环,不执行循环中剩余的语句。
continue: 停止本次循环,退回循环起始位置开始下一次循环。
switch: 根据括号里整型表达式的值,执行相应的代码后,因为有break,所以会跳出该循环。但如果没有找到一项对应,则会执行default默认的代码。
注意:括号里的值必须为整型的。
switch(integral-selector) { case integral-value1 : statement1; break; case integral-value2 : statement2; break; case integral-value3 : statement3; break; .... default : statemet; }
初始化与清理:
构造器/构造函数: 构造函数名与类名一致;
在类被加载时,就执行构造函数;
构造函数可以是无参的,也可以是有参数的
每个类都默认有个无参的构造函数,而若想在对象初始化时传入参数,就得自己手写有参数的构造函数了。当自己手写了有参数的构造函数后,默认的无参构造函数就不存在了。
清理: C中析构函数的概念??????
finalize()方法:
重载: 几个重载的方法:方法名相同,参数不同(哪怕只是参数列表顺序不同),返回值可能不同。
成员初始化: Java尽力保证所有变量在使用前都能得到恰当的初始化。
对于基本类型的全局变量如果程序员没有初始化,则编译器会有默认自动初始化值;而方法内的局部变量则会报错,提醒程序员自己初始化。
如果你没手动初始化,编译器可能会为你自动初始化; 例:int a; 编译器会自动为a赋值0,即a的默认值是0 当然你也可以手动为成员赋值; 例: int a = 5; 把5赋给a 除此外,你也可以通过构造函数初始化
Java访问权限修饰符:
private : 只有本类内部才可以访问。
frindly(默认空) : 包访问权限。同一个包里的类之间可以互相访问。
protected : 继承访问权限。被它修饰后,不同包间只有继承了它的类可以访问,同一个包内,
public :公开的。
绑定: 将方法调用和方法主体关联起来。
前期绑定:在程序执行前绑定。
后期绑定:(动态绑定或运行时绑定)在程序运行时根据对象类型绑定。而它是根据Java的反射机制来判断对象的运行时类型的。
多态:
策略设计模式:
适配器设计模式: