Java基础知识
1:数据类型
基本数据类型——内置数据类型
byte(8位):-128-127
short(16位):-32768-32767
int(32位)
long(64位)
float(32位)
double(64位)
boolean(默认值是false)
char(16位Unicode字符)——Unicode字符:是一种重要的交互和显示的通用字符编码标准,可以适用于所有已知的编码。
内置数据类型互相比较时,比较的时它们的值。
非基本数据类型——复合数据类型
String
Integer
Date
复合数据类型在进行比较时,比较的是它们在内存中存放的地址。当它们是同一个new出来的对象时,比较结果围殴true,否则为false。
Java常量
常量在程序运行时是不能被修改的的
用final关键字来修饰常量:final double PI=3.1415927;
2:进制前缀
前缀0:8进制
前缀0x:16进制
默认十进制
3:变量类型
类变量(静态变量)——独立于方法之外的变量,用static修饰
在类中以static关键字声明,必须声明在方法之外
无论类创建了多少个对象,类只拥有类变量的一份拷贝
静态变量除了被声明为常量外很少使用,静态变量初始化后不可改变
静态变量存储在静态存储区,经常被声明为常量,很少单独使用static声明变量
静态变量在第一次被访问时创建,在程序结束时销毁
import java.io.*;
public class Employee{
private static double salary;
public static String DEPARTMENT="开发人员";
public static void main(String[] args){
salary=10000;
System.out.println(DEPARTMENT+"平均工资:"+Salary);
}
}
实列变量——独立于方法之外的变量,不过没有static修饰
实例变量声明在一个类中,但在方法、构造方法和语句块之外
当一个对象被实例化之后,每个实例变量的值就跟着确定
实例变量在对象创建的时候创建,在对象被销毁的时候销毁
实例变量的值至少被一个方法、构造方法或语句块引用,使得外部能够通过这些方式获取实例变量信息
实例变量可以声明在使用前或者使用后
访问修饰符可以修饰实例变量
import java.io*;
public class Employee{
public String name;
private double salary;
public Employee(String empName){
name=empName;
}
public void setSalary(double empSal){
salary=empSal;
}
public void printEmp(){
System.out.println("名字:"+name);
System.out.pringtln("薪水:"+salary);
}
public static void main(String args[]){
Employee empOne=new("RUSH");
empOne.setSalary(88888.88);
empOne.printEmp();
}
}
局部变量——类方法中的变量
局部变量声明在方法、构造方法或语句块中
局部变量在方法、构造方法、或者语句块被执行的时候创建,当他们执行完成后,变量将会被销毁
访问修饰符不能用于局部变量
局部变量是在栈上分配的
局部变量没有默认值,所以局部变量被声明后,必须经过初始化 才可以使用
import java.io.*;
public class Test{
public void pupAge(){
int age=0;
age=age+7;
System.out.println("小狗的年龄是:"+age);
}
public static void main(String ags[]){
Test test=new Test();
test.pupAge();
}
}
4:java修饰符
访问修饰符
default(默认):在同一包内可见,不适用任何修饰符
private:在同一类中可见。使用对象:变量、方法。不能修饰类,接口
public:对所有类可见。
protect:对同一包内的类和所有子类可见。不能修饰类,接口
访问控制和继承
父类中声明为public的方法在子类中也必须为public
父类中声明为protected的方法在子类不能声明为private
父类中的private方法不能够被子类继承
非访问修饰符
static:用来修饰类方法和类变量
final:用来修饰类、方法和变量,所修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract:用来创建抽象类和抽象方法。抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类的扩充。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则出现编译错误。抽象类可以包含抽象方法和非抽象方法,抽象方法的具体实现由子类提供。
synchronized(同步)和volatile(异变的):主要用于线程的编程
synchronized声明的方法同一时间只能被一个线程访问
volatile修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。并且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。
5:Java方法
Java方法是语句的集合,它们在一起执行一个功能
方法的重载
一个类的两个方法拥有相同的名字,但是有不同的参数列表
构造方法
构造方法用来初始化该对象
构造方法和它所在的类的名字相同,但构造方法没有返回值
所有类都有构造方法,Java自动提供了一个默认的构造方法,其访问修饰符与该类的访问修饰符相同,一旦定义了自己的构造方法,默认的构造方法会失效
6:Java异常处理
引起异常的类型有:检查性异常、运行时异常、错误
检查性异常:用户错误或问题引的异常。如打开一个不存在的文件
运行时异常:与检查性异常相反,运行异常可以在编译时被忽略
错误:错误不是异常,而是脱离程序员控制的问题
声明自定义异常
所有异常都必须时Throwable的子类
如果希望写一个检查性异常类,则需继承Exception类
如果希望写一个运行时异常类,则需要继承RuntimeException类
7:Java继承
概念
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承的方法,使得子类具有父类相同的行为。
继承类型
Java不支持多继承,但支持多重继承
类型:单继承、多重继承、不同类继承同一类
继承的特性
子列拥有父类非private的属性、方法
子类可以对父类进行扩展
子类可以用自己的方式实现父类的方法
提高了类之间的耦合性——继承的缺点(耦合性越高,代码独立性越差)
继承关键字
extends:extend只能继承一个类,因为在Java中,类的继承是单一继承
implements:可以变相具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口。
public interface A{
public void eat();
public void sleep();
}
public interface B{
public void show();
}
public class C implements A,B{
}
super:实现对父类成员的访问,用来引用当前对象的父类
this:指向自己的引用
class Animal{
void eat(){
System.out.println("animal:eat");
}
}
class Dog extends Animal{
void eat(){
System.out.println("dog:eat");
}
void eatTest(){
super.eat();
this.eat();
}
}
final:把类定义为最终类,不能被继承,修饰方法时,该方法不能被子类重写
8:Java重写(Override)与重载(Overload)
方法的重写规则
参数列表与重写方法的参数列表必须完全相同
访问权限不能比父类中被重写的方法访问的权限更低
父类的成员方法只能被他的子类重写
声明为final与static的方法不能被重写
构造方法不能被重写
重载(Overload)规则
重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同可以不同
被重载的方法必须改变参数列表
被重载的方法可以改变访问修饰符
方法能够在同一个类中或者在一个子类中被重载
无法以返回值类型作为重载函数的区分标准
9:Java多态
定义
多态是同一个行为具有多个不同表现形式或形态的能力
多态就是同一个接口,使用不同的实例而执行不同的操作
多态是对象多种表现形式的体现
多态的优点
消除类型之间的耦合关系
可替换性
可扩充性
接口性
灵活性
简化性
多态存在的三个必要条件
继承
重写
父类引用指向子类的对象:Parent p=new Child();
虚函数
虚函数的存在是为了多态。如果Java中不希望某个函数具有虚函数特性,可以加上final关键字变成非虚函数。
多态的实现方式
重写、接口、抽象类和抽象方法
10:Java抽象类
定义
在面向对象的概念中,所有的对象都是通过类来描绘的,但并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
抽象类必须被继承才能被使用。
父类包含了子类集合常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
一个类只能继承一个抽象类,而一个类可以实现多个接口。
抽象方法
抽象方法只包含一个方法名,而没有方法体(没有花括号)
如果一个类包含抽象方法,那么该类必须是抽象类
任何子类必须重写父类的抽象方法,或者声明自身为抽象类
构造方法、类方法(用static修饰的方法)不能声明为抽象方法
11:Java封装
封装是指一种抽象性函式接口的实现细节部分包装、隐藏起来的方法
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段
public class Person{
private String name;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public void setName(String name){
this.name=name;
}
}
public class RunPerson{
public static void main(String args[]){
Person test=new Person();
test.setName("Rush");
test.setAge(13);
System.out.println("Name"+test.getName()+"Age:"+test.getAge());
}
}
12:java接口
13:Java枚举enum
enum Color{
red,green,blue;
}
public class Test{
public static void main(String args[]){
Color c1=Color.red;
System.out.pringtln(c1);
}
}
迭代枚举
enum Color{
red,green,blue;
}
public class Test{
public static void main(String args[]){
for(Color:myVar:Color.values()){
System.out.pringtln(myVar);
}
}
}
枚举类成员
enum Color{
red,green,blue;
private Color(){
System.out.println("Construct called for"+this.toString());
}
public void colorInfo(){
System.out.println("Universal Color");
}
}
public class Test{
public static void main(String args[]){
Color c1=Color.red;
System.out.println(c1);
c1.colorInfo();
}
}
java包(package)
为了更好的组织类,Java提供了包机制,用于区别类名的命名空间
Java高级教程
java数据结构
Java工具包提供了常用数据结构的类和接口
枚举(Enumeration)
枚举接口虽然它本身不属于数据结构,但它在其它数据结构的范畴里应用更广
枚举接口定义了一种从数据结构中取回连续元素的方式
public static void main(String args[]){
Enumeration<String> days
}
位集合(BitSet)
位集合实现了一组可以单独设置和清除的位或标志
向量(Vector)
向量类和传统数组非常相似,但是Vector的大小能根据需要动态的变化。
和数组一样,vector对象也能通过索引访问
好处:创建对象的时候不必给对象的制定大小
栈(Stack)
栈实现了一个后进先出(LIFO)的数据结构
字典(Dictionary)
字典类是一个抽象类,它定义了键映射到值的数据结构
由于是抽象类,所以它只提供了键映射到值的数据结构
哈希表(Hashtable)
哈希表提供了一种在用户定义键结构的基础上来组织数据的手段
属性(Properties)
属性继承于Hashtable.Properties类表示一个持久的属性集,属性列表中的每个键值及其对应值都是一个字符串。
Java集合框架
集合框架的目标
框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现必须是高效的
框架允许不同类型的集合,以类似的方式工作,具有高度的互操性
对一个聚合的扩展和适应必须是简单的
Java集合主要包括的两种类型的容器
集合、图
集合:存储一个元素集合(Collection);图:存储键/值对映射;Collection接口又有三种子类型,List、Set、和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等
接口
是代表集合的抽象数据类型。例如Collection、List、Set、Map等。之所以定义多个接口,是为了以不同的方式操作集合对象
实现类
是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构。例如:ArrayList、LinkedList、HashSet、HashMap
算法
是实现集合接口的对象里的方法执行的一些有用的对象,例如:搜素和排序。这些算法被称为多态,那是因为相同的方法可以在相似的几口上有着不同的实现。
Set和List的区别
Set接口实例存储是无序的,不重复的数据。List接口实例存储的是有序的,可以重复的元素。
Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变(实现类有HashSet,TreeSet)
List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其它元素位置改变(实现类有ArrayList,LinkedList,Vector)
import java.util.*;
public class Test {
public static void main(String args[]){
List<String> list=new ArrayList<String>();
list.add("Hello");
list.add("World");
list.add("RUSHRUSH");
//第一种遍历法
for(String str : list){
System.out.println(str);
}
//第二种遍历,把链表变为数组相关的内容进行遍历
String[] strArray=new String[list.size()];
list.toArray(strArray);
for(int i=0;i< strArray.length;i++){
System.out.println(strArray[i]);
}
//第三种遍历,使用迭代器进行相关遍历
Iterator<String> ite= list.iterator();
while(ite.hasNext()){
System.out.println(ite.next());
}
}
}
采用迭代器遍历数组的好处就是不用担心在遍历的过程中会超出集合的长度
遍历Map
public static void traverseMap(){
Map<String,String> map=new HashMap<String,String>();
map.put("1","I");
map.put("2","love");
map.put("3","Java");
//第一种遍历(普遍使用,二次取值)
for (String key:map.keySet()){
System.out.println("key="+key+" value="+map.get(key));
}
//第二种遍历:通过Map.entrySet使用iterator遍历key和value
Iterator<Map.Entry<String,String>> it=map.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String,String> entry=it.next();
System.out.println("key="+entry.getKey()+" value="+entry.getValue());
}
//第三种遍历方法:通过EntrySet遍历key和value
for(Map.Entry<String,String> entry:map.entrySet()){
System.out.println("key="+entry.getKey()+" value="+entry.getValue());
}
//第四种通过Map.values()遍历所有的value,但不能遍历key
for(String v:map.values()){
System.out.println("value="+v);
}
}
Java ArrayList
ArrayList<E> sites=new ArrayList<E>();
ArrayList类是一个可以动态修改的数组,与普通数组的区别就是它没有固定大小的限制,我们可以添加或删除元素
ArrayList常用方法
添加元素:add()
访问元素:get()
修改元素:set()
删除元素:remove()
计算大小:size()
ArrayList排序
Collection提供了sort()方法,可以对字符或数字列表进行排序
ArrayList<String> sites=new ArrayList<String>();
sites.add("I");
sites.add("love");
sites.add("java");
Collection.sort(sites);
for(String i:sites){
System.out.print(i+" ");
}
Java LinkedList
LinkedList<E> sites=new LinkedList<E>();
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但并不会按照线性表的顺序存储数据,而是在每一个节点里存到下一节点的地址。
实现的接口与继承的类
单向链表
双向列表
与ArrayList区别
LinkedList的增加和删除操作效率更高,而修改和查找的操作效率更低
LinkedList常用方法
在开头添加元素:addFirst()
在列表结尾添加元素:addLast()
在列表开头移除元素:removeFirst()
在列表结尾移除元素:removeLast()
获取列表开头的元素:getFirst()
获取列表结尾的元素:getLast()
Java HashSet
HashSet<E> sites=new HashSet<E>();
实现的接口与继承的类
HashSet是基于HashMap来实现的,是一个不允许有重复元素的集合
HashSet允许有null值
HashSet是无无序的,它不会记录插入的顺序
HashSet不是线程安全的,如果多个线程尝试同时修改HashSet,则最终结果是不确定的。必须在多线程访问时显示同步对HashSet的并发访问
HashSet常用方法
add()、contains()判断元素是否存在、remove()、size()
HashSet<String> sites=new HashSet<String>();
sites.add("RUSH");
sites.add("RUSH");
for(String i:sites){
System.out.println(i);//只会打印一个“Rush”
}
Java HashMap
HashMap<E,E> sites=new Hash<E,E>();
HashMap是一个散列表,他存储的内容是键值对(key-value)映射
HashMap实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步
HashMap是无序的,即不会记录插入的顺序
实现的接口与继承的类
常用的方法
put()、get(key)、remove(key)、size()、clear()
Java Iterator(迭代器)
ArrayList<String> sites=new ArrayList<String>();
sites.add("Rush");
Iterator<String> it=sites.iterator();
System.out.println(it.next());
Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可以用于迭代ArrayList和HashSet等集合
Iterator是Java迭代器最简单的实现,ListIterator是Collection API中的接口,他扩展了Iterator接口
迭代器it的两个基本操作是next、hasNext和remove
调用it.next()会返回迭代器的下一个元素,并且更新迭代器的状态
调用it.hasNext()用于检测集合中是否还有元素
调用it.remove()将迭代器返回的元素删除
Java Object类
Java Object类是所有类的父类,也就是说Java的所有类都继承了Object,子类可以使用Object的所有方法。
Object位于Java.lang包中,编译时会自动导入,我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承Object,成为Object的子类。
显式继承与隐公式继承
Java 泛型
Java泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
泛型方法
public static<E> void printArray(E[] inputArray){
//输出数组元素
for(E element:inputArray){
System.out.printf("%s",element);
}
System.out.println();
}
泛型类
public class Box<T> {
private T t;
public void add(T t){
this.t=t;
}
public T get() {
return t;
}
public static void main(String args[]){
Box<Integer> integerBox=new Box<Integer>();
integerBox.add(66);
System.out.println(integerBox.get());
}
}
类型通配符
类型通配符一般使用“ ?” 代替具体的类型参数
public static void main(String args[]){
List<String> name=new List<String>();
List<Integer> age=new List<Integer>();
name.add("RUSH");
age.add(13);
getData(name);
getData(age);
}
public static void getData(List<?> data){
System.out.println("data:"+data);
}
Java序列化与反序列化
Java提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据,有关对象的类型的信息和存储在对象中数据的类型。
将序列化写入文件之后,可以从文件中读取出来,并且对它进行反序列化。