简介 Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点  
Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等 
参考资料 IDEA Mac快捷键 
函数 简介 
函数的概念
函数就是定义在类中的具有特定功能的一段独立小程序 
函数也成为方法 
通俗的说:函数(方法)是一段可重复调用的代码段 
 
 
函数分类
普通方法:静态(static)、类方法和实例(对象)方法 
构造函数 
 
 
其它说明:
传参
有参数,则必须传入参数 
传参类型要一致 
传参个数也要一致,没有则不需要传参 
 
 
返回值
用关键字return来返回 
返回值 void 的方法默认是有一个 return 返回至调用处,一般不写 
如果有返回值,return的值要与定义的返回值类型一致 
 
 
可变参数
可变参数是 jdk1.5 的新特性 
public static 返回值类型 方法名称(数据类型… 参数名称)   会把传入的数据类型组成一个数组 
 
 
 
 
 
类方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package  com.tester.ada.function;public  class  FunctionTester  {    public  static  void  main (String[] args)  {         getDayInfo(1 );         System.out.println("调用返回值:" +getDayInfo(1 ));     }          private  static  String getDayInfo (int  day)  {         switch  (day) {             case  1 :             case  2 :             case  3 :             case  4 :             case  5 :                 System.out.println("今天是工作日" );                 break ;             case  6 :             case  7 :                 System.out.println("今天是周末" );                 break ;             default :                 System.out.println("非法的数值" );         }         return  "调用成功" ;     } } 
对象方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package  com.tester.ada.function;public  class  FunctionTester2  {    public  static  void  main (String[] args)  {         FunctionTester2  tester  =  new  FunctionTester2 ();         int  aInt  =  3 ;         double  aDouble  =  10 ;         System.out.println(tester.sum(aInt,aDouble));         System.out.println(tester.sum(8 ,12.75 ));     }     private  double  sum (int  aInt,double  aDouble)  {         return  aInt + aDouble;       } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package  com.tester.ada.function;public  class  FunctionTester3  {    public  static  void  main (String[] args)  {         int [] ints = {1 , 2 , 3 , 4 };         FunctionTester3  functionTester3  =  new  FunctionTester3 ();         System.out.println(functionTester3.plus(ints));         System.out.println(functionTester3.sum(ints));         functionTester3.say("h" ,"e" ,"ll" ,"o" );     }          private  int  plus (int [] ints)  {         int  sum  =  0 ;         for  (int  i  =  0 ; i < ints.length; i++) {             sum += ints[i];         }         return  sum;     }          private  int  sum (int [] ints)  {         int  sum1  =  0 ;         for  (int  aInt : ints         ) {             sum1 += aInt;         }         return  sum1;     }          private  void  say (String... aStr)  {         String  aString  =  null ;         for  (String aStr1 : aStr) {             System.out.print(aStr1);         }     } } 
面向对象 简介 
Java 是面向对象的语言,在 Java 中,一切皆为对象 
每一个人都是一个对象
属性:姓名、性别、年龄、身高、星座 
行为:吃饭、睡觉、学习、打豆豆 
 
 
 
类与对象 
类:共性事务的抽象,是对某一具有共性事物的描述,是概念上的定义 
对象:对象是共性事务的一个个体现,是这个类事务的一个个体或者说是类的一个实例(instance)
一个对象是数据和相关方法的集合,数据是对象的状态,方法是对象的行为 
面向对象概念构成了 Java 的核心 
面向对象具有封装 继承 多态 三大特性 
 
 
解释:人、手机、水果、苹果是一个类,具体的某个人比如你 比如我是一个具体对象  你的手机 我的手机是一个具体的对象 水果是一个更大的类包含了苹果类可以当成它的父类 
总结:① 类是抽象的、很泛的一个概念,对象是某一具体的的事物 ② 类是对象的模板,对象是类的实例 
场景:小明 坐着 D553高铁 去拉萨
类:人类、火车类、地理位置类 
对象:小明、D553高铁、拉萨 
方法、行为:坐着、去 
 
 
 
类的创建和实例化 创建类 
1 2 3 4 5 6 7 8 9 10 修饰符  class 类名称{   	   修饰符	数据类型	属性;	   ....      public  返回值数据类型	方法名称(参数类型 参数名,参数类型 参数名2 ){          return  表达式;	   }   } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package  com.tester.ada.target;public  class  MemberTester  {         String phone;     String pwd;     String regName;     String amount;          public  String register (String phone, String pwd, String regName)  {         if  (11  == phone.length() && 6  == pwd.length() && 8  >= regName.length()) {             return  "注册成功" ;         } else  {             return  "用户信息错误" ;         }     }     public  String login (String phone, String pwd)  {         if  (11  == phone.length() && 6  == pwd.length()) {             return  "Login success" ;         } else  {             return  "Login failed" ;         }     } } 
对象实例化 
语法声明
1 2 3 4 5 6 类名称	对象名称 = new  类名称(); 类名称 对象名称 = null ;	 对象名称 = new  类名称();	 
访问属性:对象名称.属性名;
为属性赋值:对象名称.属性名 = 值;
访问方法:对象名称.方法名();
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package  com.tester.ada.target;public  class  MemberExampleTester  {    public  static  void  main (String[] args)  {         MemberTester  ada  =  new  MemberTester ();         ada.phone = "13555555555" ;         ada.pwd = "123456" ;         ada.regName = "阿达" ;         System.out.println(ada.register(ada.phone, ada.pwd, ada.regName));     } } 
构造函数 概念 
构造函数是用构造对象的函数示例:User user = new User(); 
构造方法必须与类名一致 
使用 new 关键字进行调用 
在每个类中都存在一个默认的无参构造方法,默认不显示 
 
分类 
构造函数分为两类:带参和无参的构造函数
1 2 3 public  类名称(参数类型 参数名,参数类型 参数名){  ... } 
其它说明:
构造函数无返回值,返回的是一个具体的对象 
参数类型为 8 大基本数据类型、引用类型 
可以重写默认的构造函数(但是这种应该用处不大,一般都是自己重新定义一个带参数的构造函数) 
写带参数的构造函数的目的是为了方便创建对象 初始化对象 
如果显示的写了构造函数后,还想调用无参的构造函数,就必须显示声明一个无参构造函数 
 
 
注意事项 
调用构造函数语法
类名 对象名 = new 类名();  无参构造函数(默认带有一个,如果写了有参的必须显示声明后才能使用,否则找不到) 
类名 对象名 = new 类名(value1,value2);  有参的构造函数 
 
 
其它注意事项
调用带参构造函数创建对象,可以按照我们的意愿来初始化对象的属性(方便我们初始化对象) 
调用无参构造函数:对象属性值对应类型默认值 
默认构造函数是自带的(如果没有声明,则编码器会自动补齐)如果定义了带参构造函数,会覆盖无参构造函数,此时如果需要调用无参构造函数,则必须显示定义无参构造函数 
 
 
 
创建 
this 表示当前对象,也就调用的对象如果构造函数中不用 this.phone = phone; 而是采用 phone = phone; 由于就近原则两个 phone 都是使用的形参的这样就不起作用,除非把形参的变量名和属性名设置成不同的,不过一般不这样用,每次都要去起两个变量名,阅读性也不高 
构造函数中的参数可以添加非属性的其它参数 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package  com.tester.ada.target;public  class  MemberTester  {         String phone;     String pwd;     String regName;     String amount;          public  MemberTester (String phone, String pwd, String regName, String amount)  {         this .phone = phone;         this .pwd = pwd;         this .regName = regName;         this .amount = amount;     }          public  MemberTester ()  {     }          public  String register (String phone, String pwd, String regName)  {         if  (11  == phone.length() && 6  == pwd.length() && 8  >= regName.length()) {             return  "注册成功" ;         } else  {             return  "用户信息错误" ;         }     }     public  String login (String phone, String pwd)  {         if  (11  == phone.length() && 6  == pwd.length()) {             return  "Login success" ;         } else  {             return  "Login failed" ;         }     } } 
调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package  com.tester.ada.target;public  class  MemberExampleTester  {    public  static  void  main (String[] args)  {         MemberTester  ada  =  new  MemberTester ();         ada.phone = "13555555555" ;         ada.pwd = "123456" ;         ada.regName = "阿达" ;         System.out.println(ada.register(ada.phone, ada.pwd, ada.regName));         MemberTester  link  =  new  MemberTester ("13888888888" , "666666" , "link" , "8000" );         System.out.println(link.register(link.phone, link.pwd, link.regName));     } } 
内存分配 分配过程 
声明对象:Person per = null;	  声明对象时会把 per 对象存在占内存中 
实例化对象:per = new Person();   会给 per 对象开辟一段队内存空间(给对象赋的属性值就会在这块堆内存中,此时还没给对象的属性进行赋值,那么这些属性值都是类型对应的缺省值 如 String–>null int–>0 ) 
关联:栈内存中的 per 对象会保存一个地址指向堆内存地址的引用 如 0x1354464548 
 
存放分类 
栈内存
基本类型变量(基本数据类型 四类八种) 
对象引用,应用类型名称(比如上面的 per),即队堆的引用地址 
 
 
堆内存
 
全局数据区(静态区)
 
全局代码区
 
字符串池(常量池)
jdk1.7 前在方法区,1.7 后再堆中间 
共享的 String 对象 
 
 
 
内存地址 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package  com.tester.ada.target;public  class  MemoryTester  {    public  static  void  main (String[] args)  {         String  str1  =  "hello" ;                                   String  str2  =  "hello" ;                                   String  str3  =  new  String ("hello" );               String  str4  =  new  String ("hello" );               System.out.println(str1 == str2);                       System.out.println(str2 == str3);                       System.out.println(str3 == str4);                       System.out.println("---------------重新分配地址---------------" );         str3 = str1;                                            str4 = str2;                                            System.out.println(str3 == str4);                       System.out.println("---------------此时 str3 和 str4 的内存没有人引用了会成为垃圾内存,会被 gc 回收---------------" );     } } 
包装类 简介 
数据类型分类:基本数据类型和引用数据类型 
矛盾:基本数据类型不是类(类都是大写),因此 Java 为了调和矛盾引入了包装类 
解决矛盾:8 个基本数据类型对应 8 个包装类 
 
类型 
基本数据类型 
包装类 
 
 
整型 
byte 
Byte 
 
~ 
short 
Short 
 
~ 
int 
Interger 
 
~ 
long 
Long 
 
浮点型 
float 
Float 
 
~ 
double 
Double 
 
字符型 
char 
Character 
 
布尔型 
boolean 
Boolean 
 
包装类:以类的形式来管理基本数据类型
如 Integer 使用类的形式表示整数 
Integer i = new Integer(20); 
 
 
 
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package  com.tester.ada.packages;public  class  PackageClassTester  {    public  static  void  main (String[] args)  {         System.out.println(Integer.MAX_VALUE);         System.out.println(Integer.MIN_VALUE);         Integer  aInteger  =  new  Integer (10 );         System.out.println(aInteger);         Integer  Integer  =  new  Integer (20 );               Double  aDouble  =  new  Double (20.5 );         Integer  Integer2  =  30 ;         int  aInt  =  Integer.intValue();           double  adouble  =  aDouble.doubleValue();         System.out.println(aInt);         System.out.println(adouble);         int  bInt  =  Integer;     } } 
包装类常用方法 xxxValue() 
获得最大最小值 
获得最大值:Integer.MAX_VALUE 
获得最小值:Integer.MIN_VALUE 
 
将字符串转换为基本数据类型 
1 2 3 4 String  str  =  "10086" ;int  i  =  Integer.parseInt(str);double  d  =  Double。parseDouble(str);String  str2  =  String.parseString(i); 
转换 示例一 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package  com.tester.ada.conversion;public  class  TypeConversionTester  {    public  static  void  main (String[] args)  {         int  i  =  10 ;         double  doubleValue  =  20 ;         double  d  =  i;            int  j  =  (int ) doubleValue;           System.out.println("d的值为:"  + d + ",j的值为:"  + j);     } } 
示例二 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package  com.tester.ada.conversion;public  class  MemberTester  {    InvestTester  tom  =  new  InvestTester ();     BorrowerTester  jack  =  new  BorrowerTester ();     MemberTester  tom1  =  tom;         MemberTester  jack1  =  jack;         MemberTester  link  =  new  MemberTester ();     MemberTester  ada  =  new  MemberTester ();     InvestTester  link1  =  (InvestTester) link;      BorrowerTester  ada1  =  (BorrowerTester) ada;      InvestTester  tom3  =  new  InvestTester ();     BorrowerTester  tom4  =  (BorrowerTester) tom3;  } 
1 2 3 4 5 6 7 8 9 10 11 package  com.tester.ada.conversion;public  class  InvestTester  extends  MemberTester  {} 
1 2 3 4 5 6 7 8 9 10 11 package  com.tester.ada.conversion;public  class  BorrowerTester  extends  MemberTester {} 
Java 三大特性 封装 概念 
封装是 Java 三大特性之一,把对象的内部细节封闭起来,只提供操作对象属性的公共方法(把属性设置为 private,然后提供公共公开的 set get 方法) 
封装是面向对象编程语言对客观世界的模拟 例如,电视机它的内部元件就是被封闭起来了,仅仅暴露电视机按钮供人们使用,这样就没有人能任意更改咱们的元件Java 里面通过将属性设置成私有的,对属性都使用暴露出来的公共接口去操作,这样数据才更安全,更好维护 
 
目的 
通过公开方法访问数据,可以从方法里加入逻辑控制,避免不合理的访问,可进行数据检查,保证数据完整性,防止不希望的交互和非法的访问便于后期修改,提高代码的可维护性 
 
实现 
属性私有化:隐藏对象的属性和实现细节,不允许外部直接访问(设置为 private,这样就不能通过 对象.属性名 调用) 
提供公开的方法操作和访问属性(set get) 
get set 只针对属性,如果不需要进行逻辑处理可引入 lombok 后在类名前添加 @Data 注解隐式声明,针对与需要做逻辑处理的显示声明,编写逻辑处理代码 
boolean 类型的属性生成的 get set 方法中 set 会变为 is 
pom.xml引入 lombok 依赖后,在类名前添加 @Data 注解 
 
1 2 3 4 <dependency>     <groupId>org.projectlombok</groupId>     <artifactId>lombok</artifactId> </dependency> 
示例 1 2 3 4 5 6 7 <!--    依赖  --> <dependencies>     <dependency>         <groupId>org.projectlombok</groupId>         <artifactId>lombok</artifactId>     </dependency> </dependencies> 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package  com.tester.ada.trait.encapsulation;import  lombok.Data;@Data public  class  MemberTester  {    private  String phone;     private  String password;     public  void  setPhone (String phone)  {         if  (11  == phone.length())             this .phone = phone;     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package  com.tester.ada.trait.encapsulation;public  class  BorrowerTester  extends  MemberTester  {    public  static  void  main (String[] args)  {         BorrowerTester  link  =  new  BorrowerTester ();         link.setPhone("13888888888" );         System.out.println(link.getPhone());     } } 
继承 简介 
继承是 Java 三大特性的另一大特性,继承是从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,并能扩展新的能力 
一个类 A 继承 B 可以通过 extends 来实现(extends 翻译为扩展,我们通俗的称为继承) 
一个不由任何类派生出来的类称为基类(派生类) ,一个派生类(子类)最近的上层类称为该类的父类,从某一个派生类出来的类称为该类的子类 
派生类(子类)与父类之间是一个子与父的关系,子跟父之间的关系是 is a 的关系,父类和子类是 has a 的关系
水果类 –>热带水果、亚热带水果 –>芒果、香蕉、火龙果(热带水果) 
芒果 extends 热带水果 –> 子类 extends 父类 –> 子类 is a 父类 –> 芒果 is a 热带水果 = 热带水果 has a 芒果 
 
 
Java 中子类不能获得父类的构造方法 
 
语法 1 2 3 修饰符 class  SubClass  extends  SuperClass {    } 
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package  com.tester.ada.trait.inherit;import  lombok.Data;@Data public  class  MemberTester  {    private  String phone;     private  String pwd;     private  String regName;     private  double  amount; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package  com.tester.ada.trait.inherit;import  lombok.Data;@Data public  class  BorrowerTester  extends  MemberTester {         private  boolean  hasCar;     private  boolean  hasHouse; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package  com.tester.ada.trait.inherit;import  lombok.Data;@Data public  class  InvestTester  extends  MemberTester {    public  void  invest (double  doubleValue) {         System.out.println("调用:InvestTester.invest()" +"投资【" +doubleValue+"】元成功" );     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package  com.tester.ada.trait.inherit;public  class  Tester1  {    public  static  void  main (String[] args)  {         InvestTester  ada  =  new  InvestTester ();         ada.setAmount(10000 );         System.out.println(ada.getAmount());             ada.invest(3000 );            BorrowerTester  dream  =  new  BorrowerTester ();         dream.setPhone("13555555555" );           dream.setHasCar(true );           System.out.println(dream.getPhone());         System.out.println(dream.isHasCar());     } } 
多态 概念 
不同的对象对应相同的方法表现出不同的特征和响应:如对于自行车和汽车他们都定义了刹车的方法,但是它们的刹车方式却完全不同,又比如动物类都有吃东西的方法,食肉动物吃东西的方法是吃肉食,食草动物吃东西的方法是吃草 蔬菜,乐器都会发出声音,不同乐器演奏出来的表现形式各不相同 
用父类类型来接受子类的对象,Java 通过方法重写来实现多态 
通过方法重写,子类可以实现父类的某些方法,使其具有自己的特征 (例如都是人类,别人实现一个小目标是一个亿,我们的一个小目标是换个手机,因此要重写“富人”和“穷人”实现目标的方法,使其具有自己的特征) 
通过方法重写 相同的对象(变量),执行同一个方法表现出不同的行为特征,就称为多态 
多态的优点:提高代码的复用性,简化代码 
 
缘由 
在很对时候会使用父类类型接受子类对象,但是父类类型又没有实现该方法,会出现报错,如下图所示 
当然可以直接在父类中实现该方法解决报错,不过很多时候子类有自己的实现方式,比如充值的方法,针对于投资人是充值投资,针对于借款人是充值还款,因此要在子类中实现自己的充值方法 
 
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package  com.tester.ada.trait.Polymorphism;import  lombok.Data;@Data public  class  MemberTester  {    private  String phone;     private  String pwd;     private  String regName;     private  double  amount;          public  void  recharge (double  doubleValue)  {         if  (doubleValue < 100  || doubleValue > 500000 ) {             System.out.println("MemberTester.recharge():"  + "充值失败,金额必须大于等于 100 或小于等于 50万" );         } else  {             this .amount += doubleValue * 1.5 ;             System.out.println("MemberTester.recharge():"  + "尊贵的客户恭喜您获得 1.5 倍翻倍机会,当前累计充值【"  + this .getAmount() + "】成功,感谢您的使用" );         }     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package  com.tester.ada.trait.Polymorphism;public  class  BorrowerTester  extends  MemberTester  {         public  void  recharge (double  doubleValue)  {         if  (doubleValue < 100  || doubleValue > 500000 ) {             System.out.println("BorrowerTester.recharge():"  + "充值失败,金额必须大于等于 100 或小于等于 50万" );         } else  {             this .setAmount(this .getAmount() + doubleValue);             System.out.println("BorrowerTester.recharge():"  + "还款【"  + doubleValue + "】成功,累计还款"  + this .getAmount() + "元,您的信誉保持良好可继续申请借贷" );         }     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package  com.tester.ada.trait.Polymorphism;public  class  InvestTester  extends  MemberTester  {         public  void  recharge (double  doubleValue)  {         if  (doubleValue < 100  || doubleValue > 500000 ) {             System.out.println("InvestTester.recharge():"  + "充值失败,金额必须大于等于 100 或小于等于 50万" );         } else  {             this .setAmount(this .getAmount() + doubleValue);             System.out.println("InvestTester.recharge():"  + "充值【"  + doubleValue + "】成功,累计充值"  + this .getAmount() + "元,您可以去投资赚钱收益了" );         }     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package  com.tester.ada.trait.Polymorphism;public  class  Tester1  {    public  static  void  main (String[] args)  {         MemberTester  link  =  new  MemberTester ();         link.recharge(1000 );             link.recharge(2000 );             MemberTester  ada  =  new  InvestTester ();         ada.recharge(100 );           ada.recharge(1000 );          MemberTester  dream  =  new  BorrowerTester ();         dream.recharge(1000 );            dream.recharge(5000 );    ### HashSet + `无序` `不可重复` + 支持的数据类型为引用类型(类、数组)(如果添加基本数据类型会自动装箱) ```java package  com.tester.ada.common.gather.HashSet;import  java.util.HashSet;public  class  HashSetTester  {    public  static  void  main (String[] args)  {         HashSet<String> set = new  HashSet <String>();         set.add("ada" );         set.add("ada" );          set.add("link" );         set.add("dream" );         System.out.println(set.size());          System.out.println(set.contains("link" ));            System.out.println(set.isEmpty());           Object[] objs = set.toArray();             for  (Object obj : objs) {             System.out.println(obj);         }     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package  com.tester.ada.common.gather.HashSet;import  java.util.HashSet;import  java.util.Iterator;public  class  HashSetTester1  {    public  static  void  main (String[] args)  {         HashSet<String> nations = new  HashSet <String>();         nations.add("china" );         nations.add("USA" );         nations.add("Japan" );         System.out.println("===============forEach===============" );         for  (String nation : nations) {             System.out.println(nation);         }         System.out.println("===============迭代器一===============" );         for  (Iterator  nation1  =  nations.iterator(); nation1.hasNext(); ) {             System.out.println(nation1.next());         }         System.out.println("===============迭代器二===============" );         Iterator  nation2  =  nations.iterator();         while  (nation2.hasNext()) {             System.out.println(nation2.next());         }     } } 
示例二 
其实示例一种虽然实现了多态,但是并没有发挥出多态的优点:提高代码的复用性,简化代码 
也就是说这里的  recharge() 方法写了三遍实现,但是业务逻辑几乎一致(这里不考虑 1.5 倍翻倍了),因此需要优化代码示例如下 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package  com.tester.ada.trait.Polymorphism;import  lombok.Data;@Data public  class  MemberTester1  {    private  String phone;     private  String pwd;     private  String regName;     private  double  amount;     public  boolean  recharge (double  doubleValue)  {         if  (doubleValue < 100  || doubleValue > 500000 ) {             System.out.println("MemberTester.recharge():"  + "充值失败,金额必须大于等于 100 或小于等于 50万" );             return  false ;         } else  {             this .setAmount(this .getAmount() + doubleValue);             return  true ;         }     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package  com.tester.ada.trait.Polymorphism;public  class  InvestTester1  extends  MemberTester1 {    @Override      public  boolean  recharge (double  doubleValue)  {         boolean  flag  =  super .recharge(doubleValue);         if  (flag){             System.out.println("InvestTester1.recharge():"  + "充值【"  + doubleValue + "】成功,累计充值"  + this .getAmount() + "元,您可以去投资赚钱收益了" );         }         return  flag;     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package  com.tester.ada.trait.Polymorphism;public  class  BorrowerTester1  extends  MemberTester1  {    @Override      public  boolean  recharge (double  doubleValue)  {         boolean  flag  =  super .recharge(doubleValue);         if  (flag) {             System.out.println("BorrowerTester1.recharge():"  + "还款【"  + doubleValue + "】成功,累计还款"  + this .getAmount() + "元,您的信誉保持良好可继续申请借贷" );         }         return  flag;     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package  com.tester.ada.trait.Polymorphism;public  class  Tester2  {    public  static  void  main (String[] args)  {         MemberTester1  link  =  new  MemberTester1 ();         link.recharge(1000 );             link.recharge(2000 );             MemberTester1  ada  =  new  InvestTester1 ();         ada.recharge(100 );           ada.recharge(1000 );          MemberTester1  dream  =  new  BorrowerTester1 ();         dream.recharge(1000 );            dream.recharge(5000 );        } } 
常用 String API 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package  com.tester.ada.common.string;import  java.nio.charset.StandardCharsets;public  class  StringTester  {    public  static  void  main (String[] args)  {         String  str  =  new  String ("hello" );               System.out.println(str.startsWith("hel" ));         System.out.println(str.endsWith("o" ));         System.out.println(str.substring(1 ));            System.out.println(str.substring(2 , 3 ));          String  str1  =  "ada,link,test" ;         String[] str2 = str1.split("," );             for  (String str3 : str2) {             System.out.print(str3 + "\t" );         }         System.out.println();         System.out.println(str1.indexOf("a" ));                   System.out.println(str1.lastIndexOf("a" ));           System.out.println(str.contains("llo" ));         System.out.println(str.equals("Hello" ));         System.out.println(str.equalsIgnoreCase("HELlo" ));         System.out.println("a" .compareToIgnoreCase("c" ));            System.out.println("he" .concat("llo" ));              System.out.println("" .isEmpty());                System.out.println("  ada   " .trim());         System.out.println("link" .length());         System.out.println("adaTester" .toCharArray()[0 ]);         System.out.println(str.charAt(str.length() - 1 ));         System.out.println(new  String ("中国" .getBytes(StandardCharsets.UTF_8)));         System.out.println("aDA" .toUpperCase());             System.out.println("aDA" .toLowerCase());             System.out.println("ada" .replace("a" , "c" ));          System.out.println("ada" .replaceFirst("a" , "b" ));             System.out.println("ada" .replaceAll("a" , "b" ));             System.out.println(String.valueOf("hello ada" ));     } } 
常量 
对于一些固定不变的属性可通过 public static final 修饰为常量 
加了static 后只能在 static 方法中访问 
final 属性不可修改 常量不能生成 set 方法 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package  com.tester.ada.common.constant;public  class  FinalTester  {         private  static  final  String  COUNTRY  =  "中国" ;     public  static  final  String  LOCATION  =  "Earth" ;     public  static  void  main (String[] args)  {         System.out.println(FinalTester.COUNTRY);     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package  com.tester.ada.common.constant;public  class  Tester  {    public  static  void  main (String[] args)  {                  System.out.println(FinalTester.LOCATION);     } } 
集合类 简介 
Java 的集合类是特别有用的工具类 
可以存储多个对象(保存的数据类型需要是引用数据类型) 
常见的有: ArrayList、HashSet、HashMap 
 
ArrayList 
ArrayList 可变数组,数组列表,有序  可重复 
如果是一维数组是需要声明长度的,也就是固定长度,有时候并不满足要求 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package  com.tester.ada.common.gather.ArrayList;import  java.util.ArrayList;public  class  ArrayListTester  {    public  static  void  main (String[] args)  {         String[] names = new  String [40 ];         names[0 ] = "ada" ;         names[1 ] = "link" ;         names[39 ] = "Shadow" ;         ArrayList<String> arrayList = new  ArrayList <String>();           arrayList.add("ada" );         arrayList.add("link" );         arrayList.add("Shadow" );         System.out.println(arrayList.get(1 ));            arrayList.forEach(name -> System.out.println(name));             arrayList.remove(1 );                         System.out.println(arrayList.get(1 ));            System.out.println(arrayList.size());            System.out.println(arrayList.isEmpty());          System.out.println(arrayList.contains("link" ));          arrayList.set(1 , "dream" );                       System.out.println(arrayList.get(1 ));    } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package com.tester.ada.common.gather.ArrayList; import java.util.ArrayList; import java.util.Iterator; /**  * @author ada  * @ClassName ArrayListTester1  * @Description ArrayList 遍历  * @Computer Macbook pro  * @Date 2021/12/23 22:37  */ public class ArrayListTester1 {     public static void main(String[] args) {         ArrayList<Integer> arrayList = new ArrayList<Integer>();         arrayList.add(1);         arrayList.add(3);         arrayList.add(5);         System.out.println("---------------foreach---------------");         for (Integer number : arrayList) {             System.out.println(number);         }         System.out.println("---------------普通for循环---------------");         for (int i = 0; i < arrayList.size(); i++) {             System.out.println(arrayList.get(i));         }         System.out.println("---------------Lambda表达式一---------------");         arrayList.forEach(number -> {             System.out.println(number);     //写执行的逻辑         });         System.out.println("---------------Lambda表达式二---------------");         arrayList.forEach(System.out::println);         System.out.println("---------------迭代器---------------");         // 迭代器  hasNext-->如果有下一个元素就为 true  next->得到下一个元素,并且会自动去进行移动,类似 i++改变循环条件         for (Iterator iterator = arrayList.iterator(); iterator.hasNext(); ) {             Integer ints = (Integer) iterator.next();             System.out.println(ints);         }     } } 
HashSet 
无序 不可重复支持的数据类型为引用类型(类、数组)(如果添加基本数据类型会自动装箱) 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package  com.tester.ada.common.gather.HashSet;import  java.util.HashSet;public  class  HashSetTester  {    public  static  void  main (String[] args)  {         HashSet<String> set = new  HashSet <String>();         set.add("ada" );         set.add("ada" );          set.add("link" );         set.add("dream" );         System.out.println(set.size());          System.out.println(set.contains("link" ));            System.out.println(set.isEmpty());           Object[] objs = set.toArray();             for  (Object obj : objs) {             System.out.println(obj);         }     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package  com.tester.ada.common.gather.HashSet;import  java.util.HashSet;import  java.util.Iterator;public  class  HashSetTester1  {    public  static  void  main (String[] args)  {         HashSet<String> nations = new  HashSet <String>();         nations.add("china" );         nations.add("USA" );         nations.add("Japan" );         System.out.println("===============forEach===============" );         for  (String nation : nations) {             System.out.println(nation);         }         System.out.println("===============迭代器一===============" );         for  (Iterator  nation1  =  nations.iterator(); nation1.hasNext(); ) {             System.out.println(nation1.next());         }         System.out.println("===============迭代器二===============" );         Iterator  nation2  =  nations.iterator();         while  (nation2.hasNext()) {             System.out.println(nation2.next());         }     } } 
HashMap 
以键值对的形式来保存数据 
键不可以重复,重复时,后者键值覆盖前者 
键和值支持的数据类型为引用类型 
Map 可以描述任何一个对象信息 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package  com.tester.ada.common.gather.HashMap;import  java.util.Collection;import  java.util.HashMap;import  java.util.Set;public  class  HashMapTester  {    public  static  void  main (String[] args)  {         HashMap<String, Object> info = new  HashMap <String, Object>();         info.put("name" , "ada" );         info.put("age" , 18 );         info.put("age" , 25 );             info.put("Profession" , "测试工程师" );         System.out.println(info.get("age" ));          info.remove("name" );             System.out.println(info.size());             System.out.println(info.containsKey("name" ));             System.out.println(info.containsValue("工程师" ));          Set<String> allKey = info.keySet();          System.out.println(allKey);         Collection<Object> allValues = info.values();          System.out.println(allValues);         info.keySet().forEach(key -> System.out.println(key + "-->"  + info.get(key)));      } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package  com.tester.ada.common.gather.HashMap;import  java.util.HashMap;public  class  HashMapTester1  {    public  static  void  main (String[] args)  {         HashMap<String, Object> map = new  HashMap <String, Object>();         map.put("name" , "ada" );         map.put("age" , 25 );         map.put("Profession" , "测试工程师" );         System.out.println("===============forEach===============" );         for  (String key : map.keySet()) {             System.out.println(key + "--->"  + map.get(key));         }         System.out.println("===============Lambda 表达式===============" );         map.forEach((key, value) -> {             System.out.println(key + "="  + value);         });     } } 
Json 简介 
JSON (JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式对象表示为键值对 
数据由逗号分割 
花括号保存对象 
 
1 2 3 4 5 6 {   "name" :  "ada" ,    "age" :  "25" ,    "gender" :  "男" ,    "Profession" :  "测试工程师"  } 
1 2 3 4 5 [   {  "name" :  "ada" ,  "age" :  "25" , "gender" :  "男" , "Profession" :  "测试工程师" } ,    {  "name" :  "ada1" ,  "age" :  "26" , "gender" :  "男" , "Profession" :  "测试工程师1" } ,    {  "name" :  "ada2" ,  "age" :  "27" , "gender" :  "男" , "Profession" :  "测试工程师2" }  ] 
生成实体类 
除了手写还可以通过一些插件(GsonFormatPlus)快速生成实体类(在插件中搜索安装) 
创建实体类,在类中右键–>生成–>GsonFormatPlus–>粘贴 json 格式文本(GsonFormatPlus中可设置成 Lombok PS:pom.xml 需要先引入) 
 
@NoArgsConstructor 生成一个无参的构造函数 
@Data 生成 get set 方法 
 
转换 
采用第三方工具 fastJson 或 gson(这里以 fastJson 为例) 
fastJson 需要在 pom 中引入 
 
1 2 3 4 5 <dependency > 	<groupId > com.alibaba</groupId >  	<artifactId > fastjson</artifactId >  	<version > ${fastjson.version}</version >  </dependency > 
将Json字符串转对象 JSONObject.parse() 
将Json数组格式字符串转对象 JSONObject.parseArray() 
将对象转换为字符串 
 
json 字符串转 Map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package  com.tester.ada.common.json;import  com.alibaba.fastjson.JSONObject;import  java.util.Map;public  class  Json2Map  {   public  static  String  strJson  =  "{\n"  +             "  \"name\": \"ada\",\n"  +             "  \"age\": \"25\",\n"  +             "  \"gender\": \"男\",\n"  +             "  \"Profession\": \"测试工程师\"\n"  +             "}" ;     public  static  void  main (String[] args)  {                  Map  map  =  (Map)JSONObject.parse(strJson);         System.out.println(map);         } } 
Json 字符串转对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package  com.tester.ada.common.json;import  lombok.Data;import  lombok.NoArgsConstructor;@NoArgsConstructor @Data public  class  User  {    private  String name;     private  String age;     private  String gender;     private  String profession; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package  com.tester.ada.common.json;import  com.alibaba.fastjson.JSONObject;public  class  Json2Object  {    public  static  void  main (String[] args)  {                  User  users  =  JSONObject.parseObject(Json2Map.strJson, User.class);         System.out.println(users);           System.out.println(users.getName());         } } 
Maven 简介 
Maven 中央仓库   Maven 这个项目维护了一个网站,在这个上面维护了非常多开源的 jar 包,并且维护了每个 jar 包的版本便于开发者们去下载使用Maven:解决协同合作时版本问题 协同合作时传输问题 
Maven 是一个项目管理工具,它包含了一个项目对象模型(Project Object Model)–> pom.xml 
作用:项目构建(编译 打包 发布 测试 等等) 
目前大部分企业在在做项目(Java)时的首选项目构建管理工具(部分较老的企业也有用 Ant,Android 一般采用gradle) 
IDE 一般都自带有 Maven,如果没有集成开发环境需要自行下载安装配置环境变量(不管哪种方式使用,做好都修改下镜像源为国内源,本地仓库地址设置为非系统盘–>修改 settings.xml 文件 mirrors localRepository) 
Maven 添加依赖时的流程(比如我们 pom.xml 文件中添加了 fastjson 的依赖配置)
查看本地仓库是否有指定的 fastjson 的 jar 包 
如果有直接引入,如果没有自动从远程仓库搜索 fastjson 的 jar 包(如果远程仓库找不到就会报错,有可能版本不对,或者网络原因,或者在私服,或者自己打的 jar包) 
建立 Maven 项目时将从本地资源获得 Maven 的本地资源库依赖资源 
如果没找到,则从默认的 Maven(或者自己配置)的远程仓库查找下载 
 
 
POM
pom(Project Object Model)即项目对象模型,是 Maven 工作的基本单位 
位于项目目录中的 xml 文件:pom.xml 
pom.xml其中可以包含项目构建的各种配置信息 
每个项目只有一个 
 
 
Maven 的特点
可以使用 Maven 来编译你的代码 
项目打包也可以使用 Maven 来完成 
Maven 可以实现模块化管理 
Maven 可以在线管理依赖,项目依赖也很方便获取 
Maven 提供了一些丰富的插件,方便项目持续集成 
 
 
 
新建 Maven 工程参数 
groupId:分组,一般填写组织机构,如 com.incar 
artifactId:项目包名(项目打包成 jar 包的 ID,或者说 jar 包名字) 
version:版本 
name: Maven工程名称 
packaging:打包方式 (jar war pom)我用的 pom 
<relativePath>../pom.xml</relativePath>:继承父类的依赖(如果是多个子模块都需要用到的依赖,可以在父模块引用依赖子模块添加该标签即可) 
 
1 2 3 4 5 6 <groupId > com.adalucky</groupId > <artifactId > automation</artifactId > <version > V1.0.0</version > <name > endpoint</name > <packaging > pom</packaging > <description > Demo project for Spring Boot</description > 
Maven 项目结构 
src/main/java:一般是开发人员写代码的目录 
src/main/resource:开发人员放项目资源的目录 
src/test/java:放单元测试或测试人员写代码的目录 
src/main/resource:放测试资源的目录 
Maven Dependencies:通过 Maven 下载下来的项目依赖包存放的目录 
target:存放构建后文件的目录 
 
文件解析 properties解析 
Properties 类是 java.util 提供的工具类当前类名.class.getResourceAsStream 当前类读取一个文件,并且转换为输入流文件路径的更路径是/src/main/resources (可在 idea 的配置文件中修改) 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 package  com.tester.ada.Parsing.properties;import  java.io.IOException;import  java.io.InputStream;import  java.util.Properties;public  class  PropertiesTester  {    private  static  Properties  properties  =  new  Properties ();     public  static  void  main (String[] args)  {                           InputStream  in  =  PropertiesTester.class.getResourceAsStream("/config/user.properties" );         try  {             properties.load(in);             } catch  (IOException e) {             e.printStackTrace();         }         System.out.println(properties.getProperty("name" ));              System.out.println(properties.getProperty("age" ));         System.out.println(properties.getProperty("gradle" ));         System.out.println(properties.getProperty("flag" ));         System.out.println(properties.getProperty("profession" ));     }          public  static  String get (String key)  {         return  properties.getProperty(key);     }          public  static  Integer getInteger (String key)  {         String  value  =  get(key);         return  null  == value ? null  : Integer.valueOf(value);     }          public  static  Boolean getBoolean (String key)  {         String  value  =  get(key);         return  null  == value ? null  : Boolean.valueOf(value);     } } 
Xml 解析 简介 
XML:( Extensible Markup Language ) 可扩展的标记语言,类似于 html 都是标记语言(可以写逻辑处理的叫编程语言 比如 js py等等) 
特点
可扩展性,在遵循 xml 语法的前提下支持自定义和修改 
标记语言,具有结构性,意味着也是类似于 html 中的标签来定义文档 
xml 在姓名中的使用更多的是作为数据载体 而出现的,xml 和 json 都是一种数据交互格式 
非常适合万维网数据 传输,提供统一方法描述和交换结构化数据 
 
 
xml 与 html 的区别:xml 是作为数据传输的工具,是一种数据载体, html 是数据展示的工具(展示成一个网页) 
 
文档结构 
xml 的文档结构跟 HTML 类似,也是一种树形结构,从上往下发展 
父、子以及同胞等术语用于描述元素之间的关系
父元素拥有子元素 
相同层级上的子元素称为同胞(兄弟或姐妹) 
 
 
所有的元素都可以有文本内容和属性(类似 html) 
 
语法 
xml 声明语法:元素的属性值,必须要用双引号 “ “引起来    注释使用  <!-- 注释内容 --> 
 
1 <?xml version="1.0"  encoding="utf-8" ?> 
根元素:
xml 必须包含根元素,它是所有其它元素的父元素,比如一下实例中 person 就是根元素 
1 2 3 4 5 <person >   <name > ada</name >    <age > 25</age >    <gender > 男</gender >  </person > 
所有元素标签成对出现 
大小写敏感 
嵌套使用(注意嵌套顺序) 
 
 
dom4j 解析技术 dom4j : Document Object Model for Java
1 2 3 4 5 6   <dependency >   <groupId > dom4j</groupId >    <artifactId > dom4j</artifactId >    <version > ${dom4j.version}</version >  </dependency > 
创建解析器 SaxReader 对象 
获取document 对象 
获取根元素 
获取根元素下的子元素 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?xml version="1.0"  encoding="UTF-8"  ?> <Users >     <user_1  cid ="1" >          <name > John</name >          <email > john@example.com</email >          <age > 18</age >      </user_1 >      <user_2  cid ="2" >          <name > ada</name >          <email > ada@example.com</email >          <age > 22</age >      </user_2 >      <user_3  cid ="3" >          <name > link</name >          <email > link@example.com</email >          <age > 31</age >      </user_3 >  </Users > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package  com.tester.ada.Parsing.xml.entity;import  lombok.Data;@Data public  class  User  {    private  String cid;     private  String name;     private  String email;     private  String age; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 package  com.tester.ada.Parsing.xml;import  com.tester.ada.Parsing.xml.entity.User;import  org.dom4j.Document;import  org.dom4j.DocumentException;import  org.dom4j.Element;import  org.dom4j.io.SAXReader;import  java.util.ArrayList;import  java.util.List;public  class  XMLTester  {    private  static  Document document;     private  static  List<User> users = new  ArrayList <User>();      public  static  void  main (String[] args)  {         readXml("/config/user.xml" ).forEach(user -> System.out.println(user));     }          public  static  List<User> readXml (String xmlPath)  {                  SAXReader  reader  =  new  SAXReader ();         try  {             document = reader.read(XMLTester.class.getResourceAsStream(xmlPath));         } catch  (DocumentException e) {             e.printStackTrace();         }         Element  rootElement  =  document.getRootElement();         List<Element> elements = rootElement.elements();         elements.forEach(element -> {             User  user  =  new  User ();              String  elementName  =  element.getName();              String  idAttr  =  element.attribute("cid" ).getValue();              user.setCid(idAttr);             List<Element> userInfoElements = element.elements();                 userInfoElements.forEach(userInfoElement -> {                 String  tagName  =  userInfoElement.getName();                 String  tagValue  =  userInfoElement.getStringValue();                  if  ("name" .equals(tagName)) {                     user.setName(tagValue);                 } else  if  ("age" .equals(tagName)) {                     user.setAge(tagValue);                 } else  if  ("email" .equals(tagName)) {                     user.setEmail(tagValue);                 } else  if  ("cid" .equals(tagName)) {                     user.setCid(tagValue);                 }             });             users.add(user);         });         return  users;     } } 
反射 
在上面的 xml 解析时如果每次在 xml 的子节点中新增了标签,那么就需要再去添加一个 if else 做判断,不好维护,因此可通过反射技术实现通用性处理 
反射 –> 运行时编程 –> 通用性处理 
 
概念 
Java 反射机制是在运行状态中对任意一个类都能够知道这个类的所有属性和方法 
对于任意一个对象都能够调用它的任意一个方法和属性 
这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制 
 
本质 
根据类的自己吗 class 文件获取一个类的细节,包括构建出来,通过对象去调用方法、操作属性 
关键字:反射 反向获取 映射 
Java 中每一个类都有一个 class 对象,可以通过这个 class 对象获取它对应的属性和方法,然后再用这个对象的类去调用获取的方法 
在 Java 中 Class 可以用来描述所有的类 Method 可以描述所有的方法 
 
反射的实现 
1 Class<User> clazz = Class.forName("com.tester.ada.Parsing.entity.User" ); 
1 User user= clazz.newInstance(); 
1 2 String  methodName  =  "set" +(name.chaeAt(0 )+"" ).toUpperCase()+name.substring(1 );Method  method  =  clazz.getMethod(methodName,String.class);
1 method.invoke(user,value); 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package  com.tester.ada.Parsing.Mapping;import  com.tester.ada.Parsing.xml.entity.User;import  java.lang.reflect.InvocationTargetException;import  java.lang.reflect.Method;public  class  MappingTest  {    public  static  void  demo ()  {         try  {             Class<User> clazz = (Class<User>) Class.forName("com.tester.ada.Parsing.xml.entity.User" );             User  user  =  clazz.newInstance();                 String  methodName  =  "set"  + "Name" ;                  Method  method  =  clazz.getMethod(methodName, String.class);              method.invoke(user, "调用反射设值" );               System.out.println(user.getName());         } catch  (ClassNotFoundException | InstantiationException | IllegalAccessException e) {             e.printStackTrace();         } catch  (InvocationTargetException e) {             e.printStackTrace();         } catch  (NoSuchMethodException e) {             e.printStackTrace();         }     }     public  static  void  main (String[] args)  {         MappingTest.demo();     } } 
获取 Class 对象 
Class 类:用于描述类的一个类(属性、方法、构造器) 
Class 对象
封装了所有对应的类的细节信息 
将class 文件读入内存,则会创建一个 Class 对象 
Class 对象是 jvm 自动化创建的,一个类只产生一个 Class 对象 
运行时编程 
 
获得 Class 对象(获取 Test类的 Class)
通过对象调用 getClass 方法,例创建 test 对象:test.getClass(); 
通过类名去获取:Test.class; 
通过类路径注册获取:Class.forName(“com.tester.ada.Parsing.xml.entity.User”); 
 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package  com.tester.ada.Parsing.Mapping;public  class  MappingTest2  {    public  static  void  demo ()  {         Test  test  =  new  Test ();         Class  clazz1  =  test.getClass();         Class  clazz2  =  Test.class;         Class  clazz3  =  null ;         try  {             clazz3 = Class.forName("com.tester.ada.Parsing.Mapping.Test" );         } catch  (ClassNotFoundException e) {             e.printStackTrace();         }         System.out.println(clazz1 == clazz2);                System.out.println(clazz2 == clazz3);     }     public  static  void  main (String[] args)  {         MappingTest2.demo();     } } 
获取类名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package  com.tester.ada.Parsing.Mapping;public  class  MappingTest3  extends  MappingTest  {    public  static  void  demo ()  {         Class  clazz  =  MappingTest3.class;         System.out.println("当前类名【"  + clazz.getName() + "】" );             System.out.println("当前类的包名【"  + clazz.getPackage().getName() + "】" );              System.out.println("是否为接口【"  + clazz.isInterface() + "】" );                System.out.println("父类类名【"  + clazz.getSuperclass().getName() + "】" );             }     public  static  void  main (String[] args)  {         MappingTest3.demo();     } } 
获取字段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package  com.tester.ada.Parsing.Mapping;import  java.lang.reflect.Field;import  java.util.Arrays;public  class  MappingTest4  {    public  static  void  demo ()  {         Class  clazz  =  Test.class;         Field[] publicFields = clazz.getFields();         Arrays.asList(publicFields).forEach(field -> System.out.println("public字段:"  + field));         Field[] allFields = clazz.getDeclaredFields();         Arrays.asList(allFields).forEach(field -> System.out.println("所有字段:"  + field));         Arrays.asList(allFields).forEach(field -> System.out.println("字段名:"  + field.getName() + "\t字段类型:"  + field.getType() + "\t修饰符:"  + field.getModifiers()));         try  {             Field  field  =  clazz.getField("code" );             System.out.println("+++++++++++++++++++++++获取指定字符串的属性+++++++++++++++++++++++" );             System.out.println("字段名:"  + field.getName() + "\t字段类型:"  + field.getType() + "\t修饰符:"  + field.getModifiers());         } catch  (NoSuchFieldException e) {             e.printStackTrace();         }     }     public  static  void  main (String[] args)  {         demo();     } } 
获取方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package  com.tester.ada.Parsing.Mapping;import  java.lang.reflect.Method;import  java.util.Arrays;public  class  MappingTest5  {    public  static  void  demo ()  {         Class  clazz  =  Test.class;         Method[] methods = clazz.getMethods();         Arrays.asList(methods).forEach(method -> System.out.println("1.获取的是类public方法:"  + method));         Method[] allMethod = clazz.getDeclaredMethods();         Arrays.asList(allMethod).forEach(method -> System.out.println("2.获取的是类自身声明的所有方法:"  + method));         try  {             Method  demo1Method  =  clazz.getDeclaredMethod("demo1" , String.class, Integer.class);             System.out.println("3.方法的修饰符:"  + demo1Method.getModifiers() +                     "\t方法的名称:"  + demo1Method.getName() +                     "\t方法的返回值类型:"  + demo1Method.getReturnType() +                     "\t方法的参数个数:"  + demo1Method.getParameterCount() +                     "\t方法的参数类型:"  + Arrays.asList(demo1Method.getParameterTypes()).toString());         } catch  (NoSuchMethodException e) {             e.printStackTrace();         }         Method[] publicMethod = clazz.getMethods();         Arrays.asList(publicMethod).forEach(method -> System.out.println("4.获取的是类和继承实现的public方法:"  + method));     }     public  static  void  main (String[] args)  {         demo();     } } 
方法的调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package  com.tester.ada.Parsing.Mapping;import  java.lang.reflect.InvocationTargetException;import  java.lang.reflect.Method;public  class  MappingTest6  {    public  static  void  demo ()  {         Class  clazz  =  Test.class;         try  {             Method  method  =  clazz.getMethod("demo4" );               System.out.println("静态方法用 null 调用:"  + method.invoke(null ));             System.out.println("静态方法用对象调用:"  + method.invoke(clazz.newInstance()));         } catch  (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {             e.printStackTrace();         }     }     public  static  void  main (String[] args)  {         demo();     } } 
获取构造函数及创建对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package  com.tester.ada.Parsing.Mapping;import  java.lang.reflect.Constructor;import  java.lang.reflect.InvocationTargetException;import  java.util.Arrays;public  class  MappingTest7  {    public  static  void  demo ()  {         Class  clazz  =  Test.class;         Constructor[] publicConstructors = clazz.getConstructors();         Arrays.asList(publicConstructors).forEach(constructor -> System.out.println(constructor));         try  {             Constructor  testConstructors  =  clazz.getConstructor(String.class, Integer.class, Integer.class);             System.out.println("三个参数构造函数初始化对象:"  + testConstructors.newInstance("str" , 15 , 20 ));                 System.out.println("构造函数名称:"  + testConstructors.getName());             System.out.println("构造函数参数列表:"  + Arrays.asList(testConstructors.getParameterTypes()).toString());             System.out.println("构造函数参数个数:"  + testConstructors.getParameterTypes().length);             System.out.println("构造函数修饰符:"  + testConstructors.getModifiers());         } catch  (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {             e.printStackTrace();         }         try  {             Constructor  tester  =  clazz.getConstructor(null );             System.out.println("无参构造函数初始化对象:"  + tester.newInstance());          } catch  (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {             e.printStackTrace();         }     }     public  static  void  main (String[] args)  {         demo();     } } 
创建对象的两种方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package  com.tester.ada.Parsing.Mapping;import  java.lang.reflect.Constructor;import  java.lang.reflect.InvocationTargetException;public  class  MappingTest8  {    public  static  void  demo ()  {         Class  clazz  =  Test.class;         try  {             Object  obj  =  clazz.newInstance();             System.out.println(obj);         } catch  (InstantiationException e) {             e.printStackTrace();         } catch  (IllegalAccessException e) {             e.printStackTrace();         }         try  {             Constructor  c  =  clazz.getConstructor(String.class, Integer.class, Integer.class);             System.out.println(c.newInstance("a" , 20 , 35 ));         } catch  (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {             e.printStackTrace();         }     }     public  static  void  main (String[] args)  {         demo();     } } 
Excel 解析 
采用阿里巴巴的开源工具类 easyExcel 
引入依赖 lombok easyexcel 
 
1 2 3 4 5 6 7 8 9 10 <dependency >     <groupId > org.projectlombok</groupId >      <artifactId > lombok</artifactId >      <optional > true</optional >  </dependency > <dependency >     <groupId > com.alibaba</groupId >      <artifactId > easyexcel</artifactId >      <version > ${easyexcel.version}</version >  </dependency > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 package  com.tester.ada.Parsing.excel.service;import  com.alibaba.excel.EasyExcel;import  com.alibaba.excel.ExcelReader;import  com.alibaba.excel.context.AnalysisContext;import  com.alibaba.excel.event.AnalysisEventListener;import  com.alibaba.excel.read.builder.ExcelReaderBuilder;import  com.alibaba.excel.support.ExcelTypeEnum;import  java.util.Map;public  class  Dome  {    public  static  void  demo ()  {         ExcelReaderBuilder  readerBuilder  =  EasyExcel.read();         readerBuilder.file("ada/src/main/resources/excel/easyExcel.xlsx" );         readerBuilder.sheet(0 );         readerBuilder.autoCloseStream(true );         readerBuilder.excelType(ExcelTypeEnum.XLSX);         readerBuilder.registerReadListener(new  AnalysisEventListener () {                          @Override              public  void  invoke (Object o, AnalysisContext analysisContext)  {                 System.out.println(o);             }             @Override              public  void  doAfterAllAnalysed (AnalysisContext analysisContext)  {                 System.out.println("数据读取完毕" );             }         });         ExcelReader  reader  =  readerBuilder.build();         reader.readAll();         reader.finish();     }          public  static  void  demo1 ()  {         ExcelReaderBuilder  readerBuilder  =  EasyExcel.read();         readerBuilder.file("ada/src/main/resources/excel/easyExcel.xlsx" );         readerBuilder.sheet(0 );         readerBuilder.autoCloseStream(true );         readerBuilder.excelType(ExcelTypeEnum.XLSX);         readerBuilder.registerReadListener(new  AnalysisEventListener <Map<Integer, String>>() {                          @Override              public  void  invoke (Map<Integer, String> integerStringMap, AnalysisContext analysisContext)  {                 integerStringMap.forEach((k, v) -> {                     System.out.print(k + ":"  + v + "\t" );                 });                 System.out.println("" );             }             @Override              public  void  doAfterAllAnalysed (AnalysisContext analysisContext)  {                 System.out.println("数据读取完毕" );             }         });         ExcelReader  reader  =  readerBuilder.build();         reader.readAll();         reader.finish();     }     public  static  void  main (String[] args)  {         demo1();     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package  com.tester.ada.Parsing.excel.service;import  com.alibaba.excel.EasyExcel;import  com.alibaba.excel.context.AnalysisContext;import  com.alibaba.excel.event.AnalysisEventListener;import  java.util.LinkedList;import  java.util.List;import  java.util.Map;public  class  DomePro  {    public  static  void  demo ()  {         List<Map<Integer, String>> dataList = new  LinkedList <Map<Integer, String>>();         EasyExcel.read("ada/src/main/resources/excel/easyExcel.xlsx" )                 .sheet()                 .registerReadListener(new  AnalysisEventListener <Map<Integer, String>>() {                     @Override                      public  void  invoke (Map<Integer, String> integerStringMap, AnalysisContext analysisContext)  {                         dataList.add(integerStringMap);                         dataList.forEach(maps -> {                             maps.forEach((k, v) -> System.out.print(k + ":"  + v + "\t" ));                             System.out.println("" );                         });                     }                     @Override                      public  void  doAfterAllAnalysed (AnalysisContext analysisContext)  {                         System.out.println("读取完毕" );                     }                 }).doRead();     }     public  static  void  main (String[] args)  {         demo();     } } 
1 2 3 4 5 6 7 8 9 10 11 12 13 package  com.tester.ada.Parsing.excel.entity;public  abstract  class  ExecelData  {     } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package  com.tester.ada.Parsing.excel.entity;import  com.alibaba.excel.annotation.ExcelProperty;import  lombok.Data;import  java.util.Date;@Data public  class  EasyExcelEntity  extends  ExecelData  {         @ExcelProperty("ID")      private  String id;     @ExcelProperty("用户名")      private  String name;     @ExcelProperty("邮箱")      private  String email;     @ExcelProperty("性别")      private  String gander;     @ExcelProperty("积分")      private  Integer score;     @ExcelProperty("IP")      private  String IP;     @ExcelProperty("登录次数")      private  Integer count;     @ExcelProperty("加入时间")      private  Date date; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 package  com.tester.ada.Parsing.excel.service;import  com.alibaba.excel.EasyExcel;import  com.alibaba.excel.context.AnalysisContext;import  com.alibaba.excel.event.AnalysisEventListener;import  com.alibaba.excel.support.ExcelTypeEnum;import  com.alibaba.excel.write.builder.ExcelWriterBuilder;import  org.apache.poi.ss.formula.functions.T;import  java.util.LinkedList;import  java.util.List;public  class  easyExcelService  {         public  static  <T> List<T> readExcel (String Source_Path, Integer sheetIndex, Class<T> clazz)  {         if  (isExcel(Source_Path)) {             List<T> readList = new  LinkedList <>();             EasyExcel.read(Source_Path)                     .head(clazz)                      .sheet(sheetIndex)                     .registerReadListener(new  AnalysisEventListener <T>() {                         @Override                          public  void  invoke (T data, AnalysisContext analysisContext)  {                             readList.add(data);                         }                         @Override                          public  void  doAfterAllAnalysed (AnalysisContext analysisContext)  {                             System.out.println("读取完毕" );                         }                     }).doRead();             return  readList;         }         return  null ;     }          public  static  void  writeExcel (String target_Path, String Sheet_name, List<T> execelDataList, Class clazz)  {         ExcelWriterBuilder  head  =  EasyExcel.write(target_Path)                 .head(clazz);         if  (isExcel(target_Path)) {             head.excelType(ExcelTypeEnum.XLS);         } else  {             head.excelType(ExcelTypeEnum.XLSX);         }         head.sheet(Sheet_name)                 .doWrite(execelDataList);         System.out.println("数据已回写至【"  + target_Path + "】" );     }          public  static  boolean  isExcel (String Source_Path)  {         String  strType  =  Source_Path.substring(Source_Path.lastIndexOf("." ));         if  (".xls" .equalsIgnoreCase(strType) || ".xlsx" .equalsIgnoreCase(strType)) {             return  true ;         } else  {             System.err.println("文件格式不是【xls、xlsx】格式" );             System.exit(0 );         }         return  false ;     }     } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package  com.tester.ada.Parsing.excel.controlle;import  com.tester.ada.Parsing.excel.entity.EasyExcelEntity;import  com.tester.ada.Parsing.excel.service.easyExcelService;import  org.apache.poi.ss.formula.functions.T;import  java.util.List;public  class  ExcelControlle  {         public  static  <T> List<T> read (String Source_Path, Integer sheetIndex, Class<T> clazz)  {         return  easyExcelService.readExcel(Source_Path, sheetIndex, clazz);     }          public  static  void  write (String target_Path, String Sheet_name, List<T> execelDataList, Class clazz)  {         easyExcelService.writeExcel(target_Path, Sheet_name, execelDataList, clazz);     }     public  static  void  main (String[] args)  {         List  list  =  read("ada/src/main/resources/excel/easyExcel.xlsx" , 0 , EasyExcelEntity.class);         System.out.println(list.get(0 ));         write("/Users/ada/Desktop/easyExcel3.xlsx" , "第一页" , list, EasyExcelEntity.class);     } } 
异常 简介 
异常:代码在运行过程中出现的非正常情况 
异常处理:在程序出现异常时仍然可以正确执行完 
 
异常机制 
判断一门变成语言是都成熟的标准 
可以让异常处理代码和正常业务逻辑分离,保证程序健壮性、容错性、优雅性 
缺点是影响代码的可读性 
 
抛出异常 
方式一:在方法名后 throws 抛出异常的类型 
方式二:在方法名后 throws 抛出 Exception 异常(父类异常,所有的异常都继承该类) 
 
try…catch 补充知识 JRE 为什么需要安装 jdk 
jdk 提供了编译器 
jdk 提供了 java 运行环境(jre) 
jre 下有很多现成的 jar包,这些 jar 包构成了 Java SE 的一个基本框架,实现了基本的服务 
 
jre 下 jar 包的调用 
jre 下的类
java.lang 下面的包不需要导包 
其它类需要 import 导包 
 
 
自己写的类
同一个 package 直接使用,无需显示导入 
其它package 下需要 import 导包 
 
 
其它项目工程
导出 jar 包–>提供开发套件 SDK 
将 jar 包添加到私服/项目构建 
 
 
 
重载重写 方法的重载 
方法的重写 
方法的重写也称为方法的覆写 
出现继承中,子类重写父类的方法,实现多态(子类定义了和父类同名的方法) 
注意:被重写的方法修饰符(访问权限)不能比父类更严格 
 
修饰符 访问修饰符 
将程序开发人员按角色区分可分为设计者与调用者 
一个人可能同时又是设计者和调用者 
修饰符的出现是为了控制设计者设计的类有哪些东西可以被调用者使用,哪些东西不能被调用者使用,从而实现访问控制,保护类里面一些重要的部分 
private 默认修饰符 protected public 四种访问修饰符按照从左网易权限依次增大 
 
访问位置 
private 
默认修饰符 
protected 
public 
 
 
定义的类中 
√ 
√ 
√ 
√ 
 
同一个包中 
× 
√ 
√ 
√ 
 
子类中 
× 
× 
√ 
√ 
 
其它包中 
× 
× 
× 
√ 
 
非访问修饰符 static 
static:静态
可以修饰变量、函数 
类在加载到内存的时候最先加载进来的部分是静态的成员 
静态成员的访问不需要依赖对象,可直接通过类名访问: 类名.static属性;  类名.static方法(); 
静态成员在内存中只保存一份,生命周期跟类保持一致,所以静态成员是共享的 
一般不常改动的数据工具类适合声明为静态的 
 
 
访问
不用实例化对象即可调用 
static 方法只能访问 static 的属性和方法 
非 static 的属性和方法使用实例化对象进行访问 
 
 
 
final 
final:最终的
被 final 修饰的变量它的值不能再做修改被 final 修饰的函数,不能被重写 
被 final 修饰的类,不能被继承 
 
 
final声明一个常量,标识符全部使用大写 
全局常量: public static final LP_LOGIN_BIN=”xxxxx”; 
 
abstract 
interface 
interface:接口
1 2 3 public  interface  Action  {	public  Event execute (RequestContext context)  throws  Exception; } 
接口
使用 interface 关键字进行声明,类名前没有 class 
接口是一种比抽象类还抽象的一种类 
接口中只能定义方法不能有实现了的方法 
在这个接口中,定义了一个没有具体实现的方法,方法名叫做execute(),返回类型是Event。如前面所述,接口中的方法都是没有实现的。这些方法的具体实现是在实现(implements)这个接口的类中给出的 
实现接口通过 implements 关键字声明 
 
 
抽象类和接口的比较 概述 
一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了。当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用 
面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了 
既然面向对象设计的重点在于抽象,那Java接口和Java抽象类就有它存在的必然性了。 
Java接口(interface)和Java抽象类(abstract class)代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP面向对象的编程,如果要提高程序的复用率,增加程序 的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些有用的抽象类型作为你结构层次上的顶层。 
Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,究竟在什么地方,才是它们的最佳位置呢?把它们比较一下,你就可以发现了 
 
区别 
Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以(就是interface中只能定义方法,而不能有方法的实现,而在abstract class中则可以既有方法的具体实现,又有没有具体实现的抽象方法),这大概就是Java抽象类唯一的优点吧,但这个优点非常有用。如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个 新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点。倾向于使用抽象类,而不是接口,因为这更容易扩展。 
一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。在这一点上,Java接口的优势就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。(使用抽象类,那么继承这个抽象类的子类类型就比较单一,因为子类只能单继承抽象类;而子类能够同时实现多个接口,因为类型就比较多。接口和抽象类都可以定义对象,但是只能用他们的具体实现类来进行实例化。) 
从第2点不难看出,Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为。 
结合1、2点中抽象类和Java接口的各自优势,具精典的设计模式就出来了:声明类型的工作仍然由Java接口承担,但是同时给出一个Java 抽象类,且实现了这个接口,而其他同属于这个抽象类型的具体类可以选择实现这个Java接口,也可以选择继承这个抽象类,也就是说在层次结构中,Java 接口在最上面,然后紧跟着抽象类,这下两个的最大优点都能发挥到极至了。这个模式就是“缺省适配模式”。在Java语言API中用了这种模式,而且全都遵循一定的命名规范:Abstract +接口名。(A extends AbstractB implements interfaceC,那么A即可以选择实现(@Override)接口interfaceC中的方法,也可以选择不实现;A即可以选择实现(@Override)抽象类AbstractB中的方法,也可以选择不实现) 
 
目的 
Java接口和Java抽象类的存在就是为了用于具体类的实现和继承的,如果你准备写一个具体类去继承另一个具体类的话,那你的设计就有很大问题了。Java抽象类就是为了继承而存在的,它的抽象方法就是为了强制子类必须去实现的。 
使用Java接口和抽象Java类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。而不要用具体Java类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。