Java高级应用
2017-05-11 20:47:21 0 举报
AI智能生成
Java高级应用是Java技术中的重要部分,它涵盖了许多复杂且强大的功能。这些应用包括但不限于网络编程、多线程处理、数据库连接、图形用户界面设计等。Java高级应用通常需要对Java语言有深入的理解,包括面向对象编程、异常处理、泛型、集合框架等基础知识。此外,还需要熟悉各种Java API和第三方库,如JDBC用于数据库连接,Swing和JavaFX用于GUI设计,以及Netty和Spring Boot等用于构建复杂的网络应用。通过掌握Java高级应用,开发者可以创建出功能强大、性能优越的应用程序,满足各种复杂的业务需求。
作者其他创作
大纲/内容
OOP(面向对象程序语言)OOA(面向对象程序分析)OOD(面向对象程序设计)
面向对象
面向对象三大特性:封装,继承,多态
面向对象思想特点:1,更符合人类思考方式 2,将复杂简单化
面向对象编程的优势
易维护:采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的。
质量高:在设计时,可重用现有的,在以前的项目的领域中已被测试过的类使系统满足业务需求并具有较高的质量。
效率高:在软件开发时,根据设计的需要对现实世界的事物进行抽象,产生类。使用这样的方法解决问题,接近于日常生活和自然的思考方式,势必提高软件开发的效率和质量。
易拓展:由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。
栈与堆
引用数据类型放在堆里,基本数据类型放在栈里。 先进先出。
JavaDoc注释
能够从源代码中抽取类、属性、方法等的注释,形成一个配套的API帮助文档
@author 标识源代码的作者。 @deprecated 标识不应再使用的源代码实体。 @param 标识方法的参数之一。 @see 提供了一个see-also参考。 @since 标识实体首次发起的软件版本。 @return 标识该方法返回的值的类型。
类和对象
类和对象的关系
类:Java中的基本单位,具有相同属性和方法的一组对象的集合, 对象:用来描述客观事物的一个实体,由一组属性和方法构成, 关系:对象是类的具体,类是对象的抽象。
类和对象的创建
创建类:public class 类名{}
创建对象:类名 对象名 = new 类名();
例子:public class Student{}Student student = new Student();
对象的克隆
1,被克隆的类需要实现Clonenable接口2,重写克隆方法clone();3,方法中调用super.clone(); 得到复制对象。
例子://重写clone();方法@Override\tpublic Object clone() {\t\tCar car = null;\t\ttry {\t\t\tcar = (Car) super.clone();\t\t} catch (CloneNotSupportedException e) {\t\t\te.printStackTrace();\t\t}\t\treturn car;\t}
例子:\t\tCar car = new Car(\"白色\
属性和方法
类用来模拟现实生活,使用的是属性和方法类中的属性和方法统称为类成员
属性:对象的特征
例子:public class Student{ int a ;//属性 public int b(){ return a; }//方法}
方法:对象执行操作的行为
方法是由,访问修饰符+返回值+方法名+参数列表组成的
方法的调用:调用自身普通方法可以直接调用调用其他类的普通方法需要创建对象
访问修饰符:public ,protected,默认修饰符,priavte 其他地方>子类>同包>同类 从大到小排列
方法返回值:无返回值,void 有返回值,创建方法是添加返回值,有返回值需要return同类型的值
参数:
1.方法有参无参与返回值无关。2.有参方法可以有多个参数,每个参数用逗号隔开。3.参数的名字可以随便起。4.方法定义处的参数叫做形参,调用处的叫做实参。5.实参和形参的名字可以不一样,但数据类型和顺序要一样。
参数类型:限制调用方法时传入的数据类型参数名:接收传入的数据
方法传参
引用数据类型传递的是地址,基本数据类型传递值
传递地址会改变里面的值(引用传递),传递值则不会(值传递)
方法重载
方法重载的特点: 1.在同一类中。 2.方法名相同。 3.参数列表不同。 4.与访问修饰符和返回值无关。
方法重载的优点: 1.可以根据参数的不同,采用不同的方法。 2.不需要别写多个名称,只要记住一个方法名即可。
构造方法:方法名与类名一样的方法叫做构造方法, 构造方法没有返回值,默认构造方法没有参数。
构造方法分为:有参构造方法和无参构造方法,创建一个对象时,会自动调用该类的无参构造方法。
例子:public class Student{ public Student(参数列表){}}
例子:public class Student{ public Student(参数列表){} }
成员变量与局部变量
成员变量:类中的属性,定义在类中的变量
局部变量:定义在方法中的变量
成员变量与局部变量的区别: 初始值不同:成员变量有默认值,局部变量无默认值,使用前必须初始化。 作用域不同:成员变量定义类中,在整个类中可以使用,局部变量定义在方法中,只能在方法中使用。 储存位置不同:成员变量在堆中放着,局部变量在栈中放着 在同一个方法中不允许有同名的局部变量,在不同的方法中可以。 局部变量可以和成员变量同名,并且局部变量的优先级更高。
封装
将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的公共方法对隐藏信息的操作和访问。
封装的好处
1.便于使用者正确使用系统,防止错误修改属性。 2.有助于系统之间的松耦合,提高系统独立性。 3.提高软件的可重用性。 4.降低了构建大型系统的风险。
封装的步骤
1.修改属性的可见性,将访问修饰符改为private。 2.设置get/set方法。 3.设置属性的存取限制。
例子:private String name ; public String getAge() { return age; } public void setAge(int age) { this.age = String.valueOf(age); }
this关键字
代表,所在方法的所属对象的引用(谁调就是谁)
static关键字
static修饰的属性称为静态变量或者类变量,没有使用static修饰的属性称为实例(成员)变量。 static关键字的修饰方法称为静态方法或者类方法,不用static关键字修饰的方法称为实例(成员)方法。
静态方法和实例方法的区别: 静态方法: 1.可直接通过类名访问。 2.静态方法中不能使用this和super。 3.不能直接访问所属类的实例(成员)变量和实例(成员)方法。 4.可以直接访问类的静态变量和静态方法。 实例方法: 1.通过实例访问 2.可直接访问所属类的静态变量,静态方法,实例变量和实例方法。
类变量(静态变量)和实例变量的区别: 类变量: 1.被static修饰的变量,优先于对象存在。 2.随着类的加载而加载,在内存中只有一个拷贝。 3.类内部,可以在任何方法内直接访问静态变量。 4.其他类中,可以直接通过类名访问。 实例变量: 1.没有被static修饰的变量。 2.每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中又多个拷贝,互不影响。
java提供一个关键字,可以修饰成员变量,可以修饰成员方法。多个对象共用一个数据的时候,我们就用静态修饰
特点:A:随着类的加载而加载B:优先于对象存在C:被共享D:可以直接被类调用
面试题
局部(普通)代码块
普通代码块:在方法或语句中出现的{}就称为普通代码块。普通代码块和一般的语句执行顺序由他们在代码中出现的次序决定--“先出现先执行”
构造代码块
直接在类中定义且没有加static关键字的代码块称为{}构造代码块。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数。
静态代码块
在java中使用static关键字声明的代码块。静态块用于初始化类,为类的属性初始化。每个静态代码块只会执行一次。由于JVM在加载类时会执行静态代码块,所以静态代码块先于主方法执行。如果类中包含多个静态代码块,那么将按照\"先定义的代码先执行,后定义的代码后执行\"。
1 静态代码块不能存在于任何方法体内。2 静态代码块不能直接访问静态实例变量和实例方法,需要通过类的实例对象来访问。
继承is-a关系
extends关键字
实现代码复用
例子:[访问修饰符] class 子类名 extends 父类名{}
父类 || 超类 || 基类
子类 || 派生类
耦合度太高
super关键字
通过super可以调用父类的成员
1.super只能出现在子类的方法和构造方法中。 2.super调用构造方法是,只能是第一句。 3.super不能访问父类的private成员。
类似this,但不是对象,属于引用
final关键字
修饰的类,不能再被继承修饰的方法,不能被子类重写修饰的变量将变成常量,只能在初始化时进行赋值
import关键字
java中包(package)的作用,导入包
1.允许类组成较小的单元(类似文件夹),易于找到相应的文件。 2.防止命名冲突区分名字相同的类。 3.有助于实施访问权限控制。
子类的继承
可以继承
1.public和protected修饰的属性和方法,不管子类和父类是否在同一个包里。 2.默认修饰符修饰的属性和方法,子类和父类必须在同一包里。
不能继承
·
继承条件下构造方法的调用规则
1.子类构造方法没有通过super调用父类的有参构造方法,也没通过this调用自身其他构造方法系统默认调用父类的无参构造方法。 2.子类构造方法通过super调用父类的有参构造方法,执行父类相应构造方法,而不执行父类无参构造方法。 3.子类构造方法通过this调用自身其他构造方法,在相应构造方法中应用以上两条规则。
方法重写的规则
方法名相同,参数列表相同,返回值类型相同或者是其子类,访问权限不能严于父类
java中包(package)的作用:import导入包
访问修饰符
public
共有的,最高的访问级别,类的public成员所有类的成员都可以访问
protected
受保护的,类的protected成员只能被该类的成员以及其子类成员访问。还可以被同意豹中的其他类的成员访问
默认
类的成员什么修饰符都没有,又叫包修饰符,只有类本身成员和当前包下类的成员可以访问
private
私有的,不对外公开的,累的private成员只能被该类的成员访问,访问级别最低
多态
同一个引用类型,使用不同的实例而执行不同操作
1、减少类中的代码量。 2、提高代码扩展性和可维护性。
父类引用不能使用子类特有功能
多态的基本
1、继承是多态的前提。2、多态子类要重写父类的方法3、父类引用指向子类对象(子类引用不能指向子类对象)
多态性
多态性是指允许不同子类型的对象对同一消息作出不同的响应。
编译时多态
方法重载属于编译时多态
运行时多态
方法重写属于运行时多态
静态方法不能被重写,静态方法编译时看左边,运行期间看左边属性不能重写,编译时看左边,运行期间看左边
多态的应用
多态的优势:可替换性,可扩充性,接口性,灵活性,简化性,。 多态在程序中的主要应用形式:使用父类作为方法的形参和使用父类作为方法的返回值。
子类转换成父类的规则
向上转型
1、将一个父类的引用指向一个子类对象,即子类类型转换为父类类型,称为向上转型,自动类型转换。 2、通过父类的引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法。 3、通过父类的引用变量无法调用子类特有的方法。
向下转型
将一个指向子类对象的父类引用赋给一个子类的引用,即父类类型转换为子类类型,称为向下转型,强制类型转换。
instanceof关键字
作用
减少在向下转型的过程中,没有转换为真实子类类型的类型转换异常。
注意事项
对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系。
\tpublic void feed(Pet p) { \t\tif (p instanceof Dog) { \t\t\tSystem.out.print(\"喂骨头\"); \t\t} else if (p instanceof Penguin) { System.out.print(\"喂鱼\"); \t\t}}
不使用instanceof可能会发生ClassCastException异常类型转换异常。
定义工具类
在工具类中定义带参数的静态方法将重复的方法放入工具类中的静态方法中使用类名直接调用,根据参数实现多态性
实用类
字符串
String字符串
java.lang.Stringjava.lang包下不需要导包
详情见javaAPI(Java帮助文档)
引用数据类型字符串存放在字符串常量池字符串对象先在堆中创建空间,再到常量池存放字符串字符串是常量,创建之后不能改变(创建新的对象)
例子:String s = \"AbcDefG\"; String st = new String(\"ABcDefG\") String str = new String(); str = \"\";
字符串常用方法:
判断功能
.equals()字符串比较(区分大小写)
.equanls()比较引用类型的内容==比较的是,引用类型的地址
例子:s.equals(st) == true; s == st == false;
.equalsIgnoreCase()字符串比较(不区分大小写)
例子:s.equalsIgnoreCase(st) == true;
.contains()判断字符串对象是否包含指定字符串(区分大小写)
例子:s.contains(\"Abc\")==true;
.isEmpty()判断字符串对象是否为空,空为true
例子:s.isEmpty()==false;
startsWith(String str)判断字符串对象是否以给定的字符串开始。
endsWith(String str)判断字符串对象是否以给定的字符串结束。
获取功能
.length()字符串长度
例子:String s = \
转换功能
.toUpperCase()将英文字符全部转换为大写.toLowerCase()将英文字符全部转换为小写
例子:s.toLowerCase() == \"abcdefg\"; s.toUpperCase() == \"ABCDEFG\";
替换功能
\t例子:String s = \
.trim()去除左右的空字符串
例子:String s = \
.concat(\"\")字符串拼接
比较功能
compareTo(String anotherString) 按字典顺序比较,只比较第一个字母,返回两字母阿斯玛值的差
StringBuffer增强字符串
添加功能
append()添加
删除功能
deleteCharAt(int index)
其它方法
String substring(int start)
反转字符串reverse()
StringBuilder字符串生成器
此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。线程不安全,单线程情况下快
String、StringBuffer、StringBuilder三者区别
String是不可变的字符串。StringBuffer和StringBuilder是可变的字符串,是String的增强类。对字符串频繁修改(如字符串连接)时,使用StringBuffer类可以大大提高程序执行效率 StringBuffer是线程安全的,StringBuilder是线程不安全的。如果不考虑线程安全的情况下,使用StringBuilder效率更好。
日期类
java.util.Date日期格式为:年月日时分秒 java.sql.Date日期格式为:年月日java.sql.Time日期格式为:时分秒 java.sql.Timestamp日期格式为:年月日时分秒纳秒(毫微秒)
Date(日历)类
表示特定的瞬间,精确到毫秒。
构造方法:Date date = new Date();Date date = new Date(Long类型引用);
boolean after(Date when) 测试此日期是否在指定日期之后)boolean before(Date when) 测试此日期是否在指定日期之前 int compareTo(Date anotherDate) 比较两个日期的顺序
Calendar(日历)类
Calendar是抽象类是用来操作日期和时间的类,可以看作Date的增强版
第一种是 Calendar nowTime = new GregorianCalendar();第二种是Calendar calendar=Calendar.getInstance();
例子:Calendar c=Calendar.getInstance();//月份+1,星期-1 System.out.println(c.get(Calendar.YEAR)+\"年\"+(c.get(Calendar.MONTH)+1)+\"月\"+ c.get(Calendar.DATE)+\"日\"+c.get(Calendar.HOUR)+\"点\"); // 输出:2015年6月16日9点
DateFormat类
这个类是抽象类,所以不能构造方法来实例化,可以用getDateInstance()和getDateTimeInstance()这两个静态函数来进行实例化。
返回日期:getDateInstance()
返回日期+时间:getDateTimeInstance()
获得当前系统时间
long currentTime = System.currentTimeMillis();//获得当前系统时间SimpleDateFormat formatter = new SimpleDateFormat(\"yyyy年-MM月dd日-HH时mm分ss秒\");//创建时间格式Date date = new Date(currentTime);//将系统时间转换为日期类System.out.println(formatter.format(date));//使用日期格式输出时间
数学类
Math 类包含用于执行基本数学运算的方法
包装类
Number类
Number 的子类必须提供将表示的数值转换为 byte、double、float、int、long 和 short 的方法。
抽象类 Number 是 BigDecimal、BigInteger、Byte、Double、Float、Integer、Long 和 Short 类的超类。
Integer:int类型的包装类
Integer.MAX_VALUE;// 最大值Integer.MIN_VALUE;// 最小值Integer.BYTES;// 字节Integer.SIZE;// 长度
\t\tInteger valueOf = Integer.valueOf(1);// 基本类型转包装类\t\tString string2 = Integer.toString(1);// 基本数据类型转换为字符串\t\tString string = valueOf.toString();// 包装类转字符串\t\tint intValue = valueOf.intValue();// 包装类转基本类型\t\tint parseInt = Integer.parseInt(string);// 字符串转基本类型\t\tInteger valueOf2 = Integer.valueOf(string);//字符串转包装类
其他包装类
方法
byteValue() 以 byte 形式返回指定的数值。 double doubleValue() 以 double 形式返回指定的数值。 float floatValue() 以 float 形式返回指定的数值。 int intValue() 以 int 形式返回指定的数值。 long longValue() 以 long 形式返回指定的数值。 short shortValue() 以 short 形式返回指定的数值。
抽象类与接口has-a关系
abstract关键字
使用abstract修饰的类为抽象类,修饰的方法为抽象方法
抽象类与抽象方法
抽象类
抽象类不能被实例化,可以用向上转型可以有0~多个抽象方法非抽象类必须重写父类的所有抽象方法
抽象类中没有抽象构造方法和抽象静态方法。 抽象类中可以有非抽象的构造方法,且创建对象的时候可以调用。
抽象方法的使用条件
抽象方法没有方法体抽象方法必须在抽象类里抽象方法必须在子类中被实现,除非子类也是抽象类
抽象方法和普通方法的区别
抽象方法不能有方法体,普通方法有方法体。 抽象方法需要使用abstract修饰,接口中可以省略,普通方法没有。 抽象方法必须存在于抽象类或者接口中。
什么是接口
接口是一个不能实例化的类型
访问修饰符只能是public
如果抽象类中的所有方法都是抽象方法,可以用接口来表示。
实现类必须实现接口的所有方法。 实现类可以实现多个接口。(implements) 接口中的变量都是静态常量(public static final) 接口成员可以是全局常量和公共的抽象方法。
定义接口
public interface 接口名 {}
接口的多继承
public interface 接口名 extends 父接口1,父接口2,父接口3,....{}
实现接口
public 类名 implements 接口名
接口的特性
1,接口不可以被实例化2,实现类必须实现接口的所有方法3,实现类可以实现多个接口4,接口中的变量都是静态常量
面向接口编程
关心实现类有何能力,而不关心实现细节(面向接口的约定,而不考虑接口的具体实现)
接口是一种能力:
1.可以被多继承2.设计和实现完全分离3.更自然的使用多态4.更容易搭建程序框架5.更容易更换实现 。。。
接口是一种约定:
1,有些接口只有名称2,方法的实现,要通过注释约定一下,由实现类来做具体效果
抽象类和接口的比较
相同点
代表系统的抽象层;不能被实例化;都包含抽象方法:用于描述系统提供的服务,不必提供具体实现。
不相同点
在抽象类中可以包含普通方法,而接口中只能包含抽象方法。 抽象类便于复用,接口便于代码维护。 一个类只能继承一个直接父类,但可以实现多个接口。
使用原则
接口做系统与外界交互的窗口;接口提供服务;接口本身一旦制定,就不允许随意修改;抽象类可完成部分功能实现,还有部分功能可作为系统的扩展点。
Object
所有类的父类
集合
Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中
集合类存放的都是对象的引用,而非对象本身
集合的分类
collection接口
Collection接口是最基本的集合接口,可以存储一组唯一,无序的对象。Java API中所用的集合类,都是实现了Collection接口
List接口
List接口的特性是 存储一组有序不唯一的对象
ArrayList类动态数组
ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高,安全性差
ArrayList常用方法
.add();//向集合中添加元素.set();//修改集合中的元素.get();//获取集合中的元素.size();//获取集合长度.contains();//判断集合中是否存在某元素.isEmpty();//判断集合是否为空.remove();//删除元素.sublist();//集合截取
面试:.addAll();//向集合中添加集合.removeAll();//在集合中删除指定集合.containsAll();//判断集合中是否存在某集合
LinkedList类
LinkedList采用链表存储方式。插入、删除元素时效率比较高,安全性差
LinkedList常用方法
面试题:
判断对象是否相等:重写.equals()方法@Overridepublic boolean equals(Object obj) { if (obj == this) return true; if (obj.getClass() != getClass())//if(!(obj instanceof Student)) return false; Student s = (Student) obj; return this.name.equals(s.getName()) && this.age == s.getAge() && this.height == s.getHeight();}
集合去重
第一种(List集合用contains方法):
\t\tfor (Student student : 集合1) { \t\t\tif (!集合2.contains(student)) \t\t\t集合2.add(student);\t\t}
第二种:(List集合转Set集合,会变为无序)
\t\tSet<Student> set2 = new HashSet<Student>(); \t\tset2.addAll(arrayList); \t\tfor (Student student : set2) \t\t\tSystem.out.println(student.getName() + \" \" + student.getAge() + \" \" + student.getHeight());
第三种:(List集合转Set集合并用List集合重新接收,第二个List集合还是有序的)
\t\tSet<Student> set3 = new HashSet<Student>();\t\tArrayList<Student> arrayList3 = new ArrayList<Student>();\t\tfor (Student student : arrayList) {\t\t\tif (set3.add(student))\t\t\t\tarrayList3.add(student);\t\t}\t\tfor (Student student : arrayList3) \t\t\tSystem.out.println(student.getName() + \" \" + student.getAge() + \" \" + student.getHeight());\t\t
重写.hashCode()方法@Override\tpublic int hashCode() { \t\tfinal int prime = 31; \t\tint result = 1; \t\tresult = prime * result + age; \t\tresult = prime * result + height; \t\tresult = prime * result + ((name == null) ? 0 : name.hashCode()); \t\treturn result;\t}
Vector类
Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。
效率低,安全性强
Set接口
Set接口的特性是 存储一组无序唯一的对象
HashSet类
1,集合内的元素是无序排列的。2,HashSet类是非线性安全的。3,允许集合元素值为null。(只有一个,多余的无法储存)
对象去重
重写HashCode和equals
TreeSet类
根据构造方法的不用,选择使用自然排序或者比较器排序。按照实际的需求,可以对元素进行排序。并且保证唯一。
底层数据结构是二叉树。 如何保证元素唯一性呢?如何保证元素排序呢? 根据返回值是否是0,判断元素是否重复。 排序有两种方案: 元素具备比较性 实现Comparable接口 集合具备比较性 实现Comparator接口
Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
Map接口
Map接口的特性是 使用Key-value键值对的方法,key不可以重复,value可以重复key重复的话,新的key会覆盖旧的key
HashMap类
Map接口专门处理键值映射数据的存储,可以根据键实现对值的操作
HashMap类常用方法
.put();//向集合中插入键值对元素.containsKey();//判断是否存在键元素.containsValue();//判断是否存在值元素.keySet();//返回一个键元素的Set集合.values();//返回一个值元素的Collection集合.entrySet();//返回所有键值对的集合 得到一个泛型为Entry接口类型的键值对的Set集合
TreeMap类
HashTable类
线程安全的
集合的遍历
遍历Set与Map集合
将集合转为数组,再进行遍历
普通for循环
增强for循环
例子:for (String string : list2) \t\t\tSystem.out.print(string + \" \");
通过迭代器Iterator实现遍历
Iterator关键字
并发修改异常:ConcurrentModificationException在迭代器遍历的同时在增加或删除元素
解决方法:1,使用ListIterator迭代,并使用迭代器自己的方法2,使用集合for循环单独修改
例子:ListIterator<String> lt = list2.listIterator();\t\twhile (lt.hasNext()) { \t\t\tif (lt.next().equals(\"仙人掌\")) { \t\t\t\tlt.set(\"梨花\"); \t\t\t}\t\t}
迭代器
泛型
什么是泛型,即“参数化类型”
将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
为什么要使用泛型
当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。因此取出的Object类型是需要人为强制转换到原有类型的,容易产生ClassCastException异常为了达到只要编译时不出问题,转型时就不会出现异常的效果,需要用到泛型
泛型的好处
1、将运行时期异常转为编译时期2、解决黄色下划线问题3、控制类型统一,不用强制类型转化
泛型的作用范围
接收来自外部使用时候传入的类型实参。对于不同传入的类型实参,生成的相应对象实例的类型相同
泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。
在编译时存在,不存在与运行时期
泛型的分类
普通泛型
自定义泛型
在泛型接口、泛型类和泛型方法的定义过程中添加泛型通配符
泛型形参
E
Element (在集合中使用,因为集合中存放的是元素)
T
Type(Java 类)
K
Key(键)
V
Value(值)
N
Number(数值类型)
通配符?
表示不确定的java类型
类型通配符上限
只能是某一类与其子类
<? extends 类名>
类型通配符下限
只能是某一类与其父类
<? super 类名>
自定义泛型接口
例子:interface Inter<T> { void show(T t); } class InterImpl<T> implements Inter<T> { public void show(T t) { System.out.println(\"show :\"+t); } }
自定义泛型类
例子:class Point<T>{ // 此处可以随便写标识符号,T是type的简称 private T var ; // var的类型由T指定,即:由外部指定 public T getVar(){ // 返回值的类型由外部决定 return var ; } public void setVar(T var){ // 设置的类型也由外部决定 this.var = var ; } };
自定义泛型方法
受限泛型
拓展学习
.getclass()
获得一个实例的类型类
例子:A a = new A();a.getClass()==A.getClass()A是一个A类型,a对象也是一个A类型
.getData()
获取该节点的数据的方法。
.getNext()
获取下一个节点对象(Node)的方法
异常
Throwable
异常类的父类
Error类
程序本身无法恢复的严重错误
电脑自动重启,程序错误结束等不可处理的异常
Java虚拟机运行错误:Virtual MachineError
JVM不再有继续执行操作所需的内存资源时:OutOfMemoryError
Excepion类
由Java应用程序抛出和处理的非严重错误
Checked异常(非运行时异常)
除了运行时异常以外的其他由Excepion继承来的异常类。
IOException(输入输出流异常)
文件已结束异常: EOFException
文件未找到异常:FileNotFoundException
其他异常
对象强制类型转换出错:ClassCastExcepion
数字格式转换异常,如“abc”转换成数字:NumberFormaExcepion
操作数据库异常类:SQLException
运行时异常
包括RuntimeExcepion及其所有子类。(不要求程序必须对他进行处理)
算术错误情形,如以0作为除数:ArithmeticExcepion
数组下标越界:ArrayIndexOutOfBoundsExcepion
数组长度为负异常:NegativeArraySizeException
尝试访问null对象成员:NullPointerExcepion
不能加载所使用的类:ClassNotFoundExcepion
欲得到的数据类型与实际输入的类型不匹:InputMismatchExcepion
方法接收到非法参数:IllegalArgumentExcepion
并发修改异常:ConcurrentModificationException
什么是异常
异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
异常处理
Java的异常处理是通过5个关键字来实现的:try、catch、 finally、throw、throws
声明异常
throws
在方法中不处理任何的异常,而交给被调用处处理。可在方法声明出使用throws声明异常
例子:public void setID(String id) throws IllegalAccessException { \t\tif (id.length() == 7) \t\t\tthis.id = id;\t\t else throw new IllegalArgumentException(\"参数长度应为7\");\t}
throws声明抛出异常以通知调用者,可以声明多个异常用逗号隔开。
抛出异常的规则
如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。必须声明方法可抛出的任何可查异常(checked exception)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。
抛出异常
throw
异常是异常类的实例对象,我们可以创建异常类的实例对象通过throw语句抛出
throw和throws的区别
作用不同:throw用于程序员自行产生并抛出异常,throws用于声明该方法内抛出了异常。 使用的位置不同:throw位于方法体内部,可以作为单独语句使用,throws必须在方法参数列表的后面。 内容不同:throw抛出一个异常对象,且只能是一个;throws后面跟异常类,且可以跟多个异常类。
捕获异常
try-catch-fainlly
不管是否发生异常,都执行finally语句块中的内容,即使try-catch语句块中存在return,finally也会执行且先执行。不执行的唯一条件是使用System.exit(1);中断程序,退出Java虚拟机。
例子:try { \t\t\tSystem.out.println(String.format(\"%d / %d = %d\
final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)简单来说就是finally后的代码块无论如何都会被执行除非程序退出(break)。finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
如果try语句块中所有语句正常执行完毕,则catch语句块中所有语句都会被忽略。 如果try语句块在执行过程中发生异常,并且这个异常与catch语句块中声明的异常类型匹配,那么try语句块中的代码都会被忽略而执行catch中的语句。 如果try语句块在执行过程中碰到异常,而抛出的异常在catch语句块中没有声明,那么方法立即退出。 catch语句中可以加入用户自定义处理信息,也可以调用异常对象的方法输出异常信息。
多重catch需要注意顺序,越精确的异常越要写在前面
异常对象常用的方法
void printStackTrace()
输出异常的堆栈信息
异常出现在那一行
String getMessage()
返回异常信息描述字符串,是printStackTrace()输出信息的一部分
String toString()
返回异常类型字符串
System.err.println();
输出红色字体
垃圾回收
System.gc();
告诉垃圾回收器该收垃圾了
System.runFinalization();
垃圾回收器强制回收回收垃圾
结束程序
System.exit(0);
将整个虚拟机的内容都停掉,也就是说连JVM都关闭了,内存里根本不可能还有什么东西
正常退出程序
System.exit(1);//或者非0参数
非正常退出程序
System.exit(0),而System.exit(1)一般放在catch块中,当捕获到异常,需要停止程序,我们使用System.exit(1)。这个status=1是用来表示这个程序是非正常退出。
自定义异常
定义异常类,并且继承Excepion或者RuntimeException。
例子:class MyException extends Exception {// 创建自定义异常类,继承Exception类 \tpublic MyException(String ErrorMessagr) { // 构造方法 \t\tsuper(ErrorMessagr);// 父类构造方法 \t}}
编写异常类的构造方法,并且继承父类的实现
实例化自定义异常对象,并在程序中使用throw抛出。
异常链
Java向上传递异常信息的处理机制,形成异常链。
Java方法抛出的可查异常将依据调用栈、沿着方法调用的层次结构一直传递到具备处理能力的调用方法,最高层次到main方法为止。如果异常传递到main方法,而main不具备处理能力,也没有通过throws声明抛出该异常,将可能出现编译错误。
开源日志记录工具log4j
日志
软件运行的过程中离不开日志。日志主要用来记录系统运行过程中的一些重要操作信息,便于监视系统运行的情况,帮助用户避免和发现可能出现的问题,或者出现问题后根据日志找到发生的原因。
日志分类
SQL日志:记录系统执行的SQL语句异常日志:记录系统运行中发生的异常事件业务日志:记录系统的运行过程,如用户的登录。
主要输出级别及含义
fatal>error>warn>info>debug
fatal:指出严重的错误事件将会导致应用程序的退出。 !error:指出虽然发生错误事件,但是仍然不影响系统的继续运行。 warn:表明会出现潜在的错误情形。 info:在粗粒度级别上指明消息,强调应用程序的运行过程。 !debug:指出细粒度信息事件,对调试应用程序是非常有帮助的
log4j的作用
控制日志的输出级别控制日志信息输送的目的地是控制台、文件等控制每一条日志的输出格式
添加log4日志的步骤
1、在项目中加入log4j的JAR文件2、创建log4j.properties文件3、配置日志信息4、使用log4j记录日志信息
IO流
什么是文件
文件可认为是相关记录或放在一起的数据的集合
File类
文件和目录路径名的抽象表示形式。
例子:String str = \"F:\" + File.separator + \"JAVA\" + File.separator + \"file.txt\";\t\tFile f1 = new File(str);
File对象用来获取或处理与磁盘文件相关的信息例如权限,时间,日期和目录路径
\t\tSystem.out.println(\"相对路径: \" + f1.getPath());\t\tSystem.out.println(\"文件名或目录名: \" + f1.getName());\t\tSystem.out.println(\"绝对路径: \" + f1.getAbsolutePath());\t\tSystem.out.println(\"返回父路径名,没有则返回Null: \" + f1.getParent());\t\tSystem.out.println(\"测试文件是否存在:\" + (f1.exists() ? \"exists\" : \"does not exist\"));\t\tSystem.out.println(\"测试文件是否可以修改:\" + (f1.canWrite() ? \"is writeable\" : \"is not writeable\"));\t\tSystem.out.println(\"是否可以读取\"+(f1.canRead() ? \"is readable\" : \"is not readable\"));\t\tSystem.out.println(\"测试文件名是否是目录 \" + (f1.isDirectory() ? \"\" : \"not\" + \" a directory\"));\t\tSystem.out.println(\"测试文件名是否是标准文件 \"+(f1.isFile() ? \"is normal file\" : \"might be a named pipe\"));\t\tSystem.out.println(\"测试文件名是否是绝对路径 \"+(f1.isAbsolute() ? \"is absolute\" : \"is not absolute\"));\t\tSystem.out.println(\"文件最后一次被修改的时间: \" + f1.lastModified());\t\tSystem.out.println(\"文件的长度: \" + f1.length() + \" Bytes\");
创建新文件:boolean createNewFile();创建文件夹:boolean mkdir();创建多重文件夹:boolean mkdirs(); 单层删除文件:boolean delect();列出可用的系统文件根目录:static File[] listRoots();指定目录下的文件名数组:String[] list();返回指定目录下的文件及文件夹对象数组:File[] listFiles();
流
IO流的分类
分类
实体流:实体流可以直接处理数据源装饰流:装饰流不能直接处理数据源,需要与其他装饰流或者实体流共同使用
因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。
字符流
Reader和Writer读文本
输入流数据读取到程序里
Reader作为基类
缓冲读取流:BufferedReader:
提供通用的缓冲方式文本读取,而且提供了很实用的readLine,读取一个文本行,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
字符数组类:CharArrayReader
过滤输入类:FileReader
字符输入类:InputStreamReader
管道输入类:PipedReader
字符串输入类:StringReader
输出流当程序将输出储存起来
Writer作为基类
字节流
InputStream和OutputStream读图片视频
输入字节流InputStream
基本介质流
Byte数组输入流:ByteArrayInputStream
字串缓冲输入流:StringBufferInputStream
文件输入流(实体流):FileInputStream
数据输入流(装饰流):DataInputStream
.write(.getByte())//按照系统编码格式编码规定个数,循环遍历
.writeUTF()//输入不限定长度的UTF-8格式的文本.readUTF()//输出不限定长度的UTF-8格式文本
管道输入流(从与其它线程共用的管道中读取数据):PipedInputStream
对象输入流序列化(装饰流):ObjectInputStream
输出字节流OutputStream
线程
什么是并发:
一个程序同时处理多个任务叫做并发。
什么是程序
是对数据描述与操作的代码的集合。
什么是线程
是系统运行程序的基本单位。(正在运行的程序)
每个进程都有自己独立的一块内存空间,一组系统资源。 每个进程的内部数据和状态都是独立的。
进程的特点:动态性,并发性,独立性
进程内部的一个执行单元,一个进程在其执行过程中可以产生多个线程。
线程的特点:
1.一个进程可以包含多个线程,而一个线程至少要有一父进程。2.线程可以有自己的堆栈,程序计数器和局部变量。3.线程与父进程的其他线程共享进程所有的资源。4.独立运行,采用抢占方式。 5.一个线程可以创建和删除另外一个线程。6.同一个进程中的多个线程之间可以并发执行。 7.线程的调度管理是由进程来完成的。
线程和进程的区别:
一个进程中至少要有一个线程。 资源分配给进程,同一进程的所有线程共享该进程的所有资源。处理机分配给线程,即真正在处理机上运行的是线程。
线程的级别分类:
核心级线程:和系统任务相关的线程,负责处理不同进程之间的多个线程。
用户级线程:程序需要而编写的线程即用户级线程。
线程的状态:
新生状态`可运行状态`堵塞状态`死亡状态。
使用线程
创建线程的两种方法
继承Thread类
实现Runnable接口由于单继承的原因,一般我们用Runnable接口实现创建线程
使用线程的步骤:
1.定义一个线程,同时指明这个线程所要执行的代码。2.创建线程对象。3.启动线程。4.终止线程。
线程的方法
run()执行任务操作的方法start()使该线程开始执行sleep(long millis)在指定的毫秒内让当前线程休眠Thread.currentThread().getName()获得当前线程的名称.setName()修改当前线程的名称int getPriority返回线程的优先级setPtiority(int a)更改线程的优先级Thread.State getState()返回线程的状态isAlive()测试线程是否处于活跃状态join()等待该线程终止interrupt()中断线程yield()暂停当前正在执行的线程对象,并执行其他线程
synchronized关键字
java的内置锁每个java对象都可以用做一个实现同步的锁
使用原因
原因1:共享资源原因2:延迟性原因3:随机性
使用方法
修饰代码块
修饰一个代码块,有参数,参数是任意锁,但要保证参数相同继承Thread类时,需要将任意对象改为static或使用反射,本类.class
修饰方法
修饰一个方法,方法中的对象默认为this对象,所以在继承Thread类的时候需要将方法转为静态
Socket网络编程
http://elim.iteye.com/blog/1979837
自由主题
0 条评论
回复 删除
下一页