java零基础
Java用途
如何学
冯.诺依曼体系结构
计算机软件
软件是用户与硬件之间的接口界面。用户主要是通过软件与计算机进行交流。软件是计算机系统设计的重要依据。为了方便用户,为了使计算机系统具有较高的总体效用,在设计计算机系统时,必须通盘考虑软件与硬件的结合,以及用户的要求和软件的要求。
软件的含义
应用软件
应用软件是为了某种特定的用途而被开发的软件。它可以是一个特定的程序,比如一个图像浏览器。也可以是一组功能联系紧密,可以互相协作的程序的集合,比如微软的Office软件。也可以是一个由众多独立程序组成的庞大的软件系统,比如数据库管理系统。
较常见的有:文字处理软件如WPS、Word等
信息管理软件
辅助设计软件如AutoCAD
系统软件
系统软件是各类操作系统,如windows、Linux、UNIX等,还包括操作系统的补丁程序及硬件驱动程序,都是系统软件类。
基本Dos命令
打开CMD的方式
-
开始+系统+命令提示符
-
Win键+R输入cmd打开控制台(推荐使用)
-
在任意的文件夹下面,按住shift键+鼠标右键点击,在此处打开命令行窗口
-
资源管理器的地址栏前面加上 cmd 路径
-
管理员方式运行:选择以管理员方式运行
常见的Dos命令
#盘符切换 #查看当前目录下的所有文件 dir #切换目录 cd change directory #返回上一级 cd .. #清理屏幕 cls #查看ip地址 ipconfig #ping命令 #文件操作 md 目录名 rd 目录名 cd> 文件名 del 文件名
Java特性和优势
-
简单性
-
面向对象
-
可移植性
-
高性能
-
分布式
-
动态性
-
多线程
-
安全性
-
健壮性
Java三大版本
-
Write Once、Run Anywhere
-
JavaSE:标准版(桌面程序,控制台开发...)
-
JavaME:嵌入式开发(手机,小家电......)
-
JavaEE:E企业级开发(web端,服务器开发...)
JDK、JRE、JVM
JDK : Java Development Kit
JRE:Java Runtime Environment java运行环境
JVM : JAVA Virtual Machine Java虚拟机(实现一次编译到处运行
JDK包括JRE,在JRE上扩展开发工具
有JRE就能运行java程序
卸载JDk
卸载JDK
-
删除Java的安装目录
-
删除JAVA_HOME
-
删除path下关于Java的目录
-
java -version
安装JDK
-
百度搜索JDK8,找到下载地址
-
同意协议
-
下载电脑对应的版本
-
双击安装JDK
-
记住安装的路径
-
配置环境变量
-
我的电脑-->右键-->属性
-
环境变量-->JAVA_HOME
-
配置path变量测试
-
-
JDK是否安装成功 1.打开cmd 2.java -version
-
第一个程序”Hello,World"
1.随便新建一个文件夹,存放代码
2.新建一个Java文件
-
文件后缀名为.java。
-
Hello.java
-
【注意点】系统可能没有显示文件后缀名,我们需要手动打
3.编写代码
public class Hello{ public static void main(String[] args){ System.out.print("Hello,World!"); } }
-
javac编译命令,会生成一个Java文件
-
运行class文件,java.class文件
可能会遇到的情况
-
每个单词的大小不能出现问题,Java是大小写敏感的
-
尽量使用英文;
-
文件名和类名必须保证一致,并且首字母大写
-
符号使用的了中文
Java运行机制
-
编译型 相当于一下把一本英文书翻译成中文书(损失较大)数度较快
-
解释型 看一下翻译一下,改了得从头再来(网页 )
-
Java文件经过编译变成class文件在经解释可执行文件
Java注释
单行注释://
多行注释:/* */
文档注释:/** **/
Java标识符
关键字
Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
标识符注意点
-
所有字符都以字母、美元符、下划线开始
-
首字符后可以是字母、数字的任何字符、美元符、下划线。
-
不能使用关键字作为变量名或方法名。
-
标识符是大小写敏感的
数据类型
-
强类型语言 :要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用
-
Java的数据类型分为两大类
-
基本类型
-
引用类型
类、接口、数组
整数拓展:
int i=10; //二进制 int i2=010; //8进制 int i3=0x10; //十六进制 System.out.println(i);//结果为2 System.out.println(i2);//结果为8 System.out.println(i3);//结果为16
-
浮点数扩展:
//浮点数扩展? 银行业务怎末表示? //BigDecimal 类 //float 有限 离散 有误差 //double 最好完全用浮点数比较 float f=0.1f; double d=1.0/10; System.out.println(f==d);//false System.out.println(f); System.out.println(d);
强制转换和布尔值扩展:
char ch1 = 'a'; char ch2 = 'c'; System.out.println(ch1);//a System.out.println((int) ch1);//97 强制转换 System.out.println(ch2);//c System.out.println((int) ch2);//99 //所有字符都是数字 //编码 Unicode表 97:a //U0000 UFFFF char ch3 = '\u0061'; System.out.println(ch3);//a //转义字符 //\t 制表符 \n 换行符 //布尔值扩展 System.out.println("======================================================================"); boolean flag1 = true; if (flag1 == true) { System.out.println(ch1); } if(flag1){ System.out.println(ch1);
数据类型转换
-
不能对布尔值进行转换
-
不能把对象类型转换为不相干的类型
-
在把高容量转换到低容量的时候,强制转换
-
转换的时候可能存在内存溢出,或者精度问题!
变量
-
变量是什么:就是可以变化的量。
-
Java是一种强类型语言,每个变量都必须声明其类型。
-
Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
-
注意事项
-
每个变量都有类型,类型可以是基本类型,也可以是引用类型。
-
变量名必须是合法的标识符。
局部变量和全局变量
-
在方法内 局部变量优于全局变量
-
public class Demo1 { //类变量 static double salary=2400; //属性:变量 //实例变量:从属于对象;如果不自行初始化,这个类型的默认值0 0.0/布尔值:默认是false //除了基本类型,其余的默认值都是nuLL; String name="傻逼"; String age="2"; //属性 :变量 //main方法 public static void main(String[] args){ //局部变量得声明和初始化 int a=1; String name="何国理"; char ch1='a'; System.out.println(a); //生命周期只在这个方法内 //变量类型 变量名字=new Demo1 Demo1 demo1 =new Demo1(); System.out.println(demo1.name); System.out.println(demo1.age); System.out.println(salary ); } //其他方法 public void add(){ } }
常量
static(静态常量)
public class Demo2 { //修饰符不分先后 static final double PI=3.14; public static void main(String[] args){ System.out.println(PI); } }
变量命名规范
-
所有变量、方法、类名:见名知意
-
类成员变量:首字母小写和驼峰原则: monthSalary除了第一个单词以外,后面的单词首字母大写lastname lastName
-
局部变量:首字母小写和驼峰原则
-
常量:大写字母和下划线:MAX_VALUE
-
类名:首字母大写和驼峰原则: Man,GoodMan
-
方法名:首字母小写和驼峰原则: run(). runRun0
运算符
-
算术运算符: +,-,*,/,%,++,--
-
赋值运算符: =
-
关系运算符: >,<,>=,<=,==,!= instanceof
-
逻辑运算符: &&,||,!
-
位运算符: &,|,^,~,>>,<<,>>>(了解!!! )
-
条件运算符: ?∶
-
扩展赋值运算符: +=,-=,*=,/=
-
位运算
-
字符串连接符
包机制
-
包相当于一个文件夹
-
包的语法格式
package pkg1[.pkg2[.pkg3]];
-
一般利用公司域名倒置作为包名
-
使用某一包的成员,需要使用import导包
JavaDoc
-
javadoc命令是用来生成自己API文档的
-
参数信息
-
@author 作者名
-
@version版本号
-
@since指明需要最早使用的jdk版本
-
@param参数名
-
@return返回值情况
-
@throws 异常抛出情况
-
-
命令行操作:
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
-
ideal操作:“工具“——”生成Doc“——
Java流程控制
Scanner对象
-
通过Scanner类来获取用户的输入。
-
基本语法:
Scanner s=new Scanner(System.in);
-
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext() 与hasNextLine()判断是否还有输入的数据
-
next():
-
一定要读取到有效字符后才可以结束输入。
-
对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
-
只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
-
next()不能得到带有空格的字符串。
-
-
nextLine():
-
以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。
-
可以获得空白。
-
顺序结构
选择结构
-
if单选择结构
-
我们很多时候需要去判断一个东西是否可行,然后我们才去执行,运样一个过程在程序中用if语句来表示
-
-
if双选择结构
-
语法
if(布尔表达式){ //如果布尔表达式的值为true}else{ //如果布尔表达式的值为false}
-
-
if多选择结构嵌套的if结构
-
switch多选择结构
循环结构
-
while循环
-
语法``` while(){
//循环语句
}```
-
只要布尔表达式为true,循环就会一直执行下去。
-
我们大多数情况是会让循环停止下来的,我们需要一个让表达式失效的方式来结束循少部分情况需要循环一直执行,比如服务器的请求响应监听等。
-
循环条件一直为true就会造成无限循环【死循环】
-
我们正常的业务编程中应该尽量避免死循环。会影响程序性能或者造成程序卡死奔溃!
-
-
-
do...while循环
-
语法```do{
//代码语句
}while(布尔表达式);
-
对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
-
do...while循环和while循环相似,不同的是,do...while循环至少会执行一次。
-
While和do-While的区别: while先判断后执行。dowhile是先执行后判断! Do...while总是保证循环体会被至少执行一次!这是他们的主要差别。
-
-
for循环
break continue goto
-
break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)
-
continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
-
关于goto关键字 goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式使用;Java没有goto。然而,在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子---带标签的break和continue。“标签”是指后面跟一个冒号的标识符,例如:lable: 对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。
Java 方法详解
-
Java方法是语句的集合,它们在一起执行一个功能。
-
方法是解决一类问题的步骤的有序组合 方法包含于类或对象中
-
方法在程序中被创建,在其他地方被引用
-
-
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。
方法的定义
方法的调用
-
调用方法:对象名.方法名(实参列表)
-
Java支持两种调用方法的方式,根据方法是否返回值来选择。当方法返回一个值的时候,方法调用通常被当做一个值。例如: int larger = max( 30,40);
-
如果方法返回值是void,方法调用一定是一条语句。
方法的重载
-
重载就是在一个类中,有相同的函数名称,但形参不同的函数。 方法的重载的规则: ◆方法名称必须相同。 ◆参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
◆方法的返回类型可以相同也可以不相同 ◆仅仅返回类型不同不足以成为方法的重载。
可变参数
-
在方法声明中,在指定参数类型后加一个省略号(.…)。
-
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
递归
-
递归就是自己调用自己
-
利用递归能使复杂的问题简单化
-
递归结构包括两个部分:
-
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
-
递归体:什么时候需要调用自身方法。
-
适用基数较小的情况
-
数组
数组的定义
-
数组是相同类型数据的有序集合.
-
数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
-
其中,每一个数据称作一个数组元素,每个数组元素可以通过一个 下标来访问它们。
数组的声明与创建
-
首先要声明数组才能使用。声明方法:
dataType[] arrayRefVar;
-
使用new操作符来创建数组。
dataType[] arrayRefVar=new arrayRefVar[size];
-
数组的元素是通过索引访问的,数组索引从0开始。
-
获取数组长度:
array.length
内存分析
Java内存分析
三种初始化
-
静态初始化
int[] a={1,2,3}; Man[] mans={new Man(1,1),new Man(2,3)};
-
动态初始化
int[] a=new int[2]; a[0]=1; a[1]=2;
-
数组默认的初始化
-
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个素也被按照实例变量同样的方式被隐式初始化。
-
数组的四个基本特点
-
其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
-
其元素必须是相同类型,不允许出现混合类型。
-
数组中的元素可以是任何数据类型,包括基本类型和引用类型。
-
数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
数组边界
-
下标的合法区间[0, length-1],如果越界就会报错;
-
ArraylndexOutOfBoundsException :数组下标越界异常!
面向对象
什么是面向对象
-
面向对象编程(Object-Oriented Programming, OOP)
-
面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
-
抽象
-
三大特性:
-
封装
-
继承
-
多态
-
-
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类, 是抽象的,是对对象的抽象
-
从代码运行角度考虑是先有类后有对象。类是对象的模板。
创建对象
-
类:抽象的,实例化 类实例化后会返回一个自己的对象! student对象就是一个student类的具体实例!
-
使用new关键字创建对象
-
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
-
类中的构造器也称为构造方法,是任进行创建对相的时候必须调用的。特点: 1.必须和类的名字相同 2.必须没有返回类型,也不能写void
-
构造器必须要掌握
-
构造器; 1.和类名相同
2.没有返回值
-
作用:
-
1.new本质在调用构造方法
2.初始化对象的值 注意点: 1.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造 ALt +Insert
创建对象内存对象分析
封装
-
该露的露,该藏的藏 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
-
封装(数据的隐藏) 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。 记住这句话就够了:属性私有(private),get/set
-
作用:
-
提高程序的安全性,保护数据
-
隐藏代码的实现细节
-
统一接口
-
系统可维护增加了
-
继承
-
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
-
extends的意思是“扩展”。子类是父类的扩展。 JAVA中类只有单继承,没有多继承! 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
-
继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。子类和父类之间,从意义上讲应该具有"is a"的关系.
-
object类
-
super
-
方法重写
-
在java中,所有的类,都默认直接或者间接继承object
-
私有的无法被继承
-
new会执行无参构造,子类执行无参构造同时调用了父类的无参构造
-
调用父类的构造器必须在子类的第一行
super注意点:
-
super调用父类的构造方法,必须在构造方法的第一个
-
super 必须只能出现在子类的方法或者构造方法中!
-
super和 this 不能同时调用构造方法!
-
Vs this: 代表的对象不同: this:本身调用者这个对象
super:代表父类对象的应用前提 this:没哟继承也可以使用 super:只能在继承条件才可以使用构造方法 this();本类的构造
super():父类的构造!
-
-
方法的重写
b是a的父类
重写都是方法的重写
-
重写:需要有继承关系,子类重写父类的方法!
-
方法名必须相同
-
参数列表列表必须相同
-
修饰符:范围可以扩大但不能缩小: public>Protected>Default>private
-
抛出的异常:范围,可以被缩小,但不能扩大; ClassNotFoundException --> Exception(大)
-
重写,子类的方法和父类必要一致;方法体不同!
-
-
为什么需要重写:
-
父类的功能,子类不一定需要,或者不一定满足!
-
Alt+ Insert ;override;
-
多态
定义:即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
多态注意事项: 1.多态是方法的多态,属性没有多态 2.父类和子类,有联系类型转换异常! ClasscastException ! 3.存在条件:继承关系,方法需要重写,父类引用指向子类对象!Father f1 = new Son( );
不存在多态:
-
static方法,属于类,它不属于实例
-
final常量;
-
private方法;
-
instanceof 判断是否存在父子关系
static关键字
在类中,用static声明的成员变量为静态成员变量,也成为类变量。类变量的生命周期和类相同,在整个应用程序执行期间都有效。
这里要强调一下:
static修饰的成员变量和方法,从属于类
普通变量和方法从属于对象
静态方法不能调用非静态成员,编译会报错
static关键字的用途 一句话描述就是:方便在没有创建对象的情况下进行调用(方法/变量)。
显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
static可以用来修饰类的成员方法、类的成员变量,另外也可以编写static代码块来优化程序性能
static方法 static方法也成为静态方法,由于静态方法不依赖于任何对象就可以直接访问,因此对于静态方法来说,是没有this的,因为不依附于任何对象,既然都没有对象,就谈不上this了,并且由于此特性,在静态方法中不能访问类的非静态成员变量和非静态方法,因为非静态成员变量和非静态方法都必须依赖于具体的对象才能被调用。
虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法和静态成员变量。
代码示例:
public class Student { private static int age=3;//静态变量 多线程 private char sex;//非静态变量 public void run(){ System.out.println("11"); go();//非静态方法能调用静态放法 反之不行 } public static void go(){ System.out.println("22"); } public static void main(String[] args) { Student student=new Student(); System.out.println(student.age); System.out.println(student.sex); System.out.println(Student.age); System.out.println("==============================="); //run(); 错误 无法引用静态方法 student.run(); go(); student.go(); } } //静态变量可以使用类名.变量调用
static变量 static变量也称为静态变量,静态变量和非静态变量的区别:
静态变量被所有对象共享,在内存中只有一个副本,在类初次加载的时候才会初始化
非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响
static成员变量初始化顺序按照定义的顺序来进行初始化
static块 构造方法用于对象的初始化。静态初始化块,用于类的初始化操作。
在静态初始化块中不能直接访问非staic成员。
public class Person { //第二个运行 可以用来赋初始值 { System.out.println("这是匿名代码块"); } //第一个运行 有多个对象只执行一次 static{ } //第三个运行 public Person(){ System.out.println("无参构造"); } public static void main(String[] args) { Person person1=new Person(); Person person2=new Person(); } }
static块的作用 静态初始化块的作用就是:提升程序性能。
为什么说静态初始化块能提升程序性能,代码示例如下:
class Person{ private Date birthDate;
public Person(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { Date startDate = Date.valueOf("1946"); Date endDate = Date.valueOf("1964"); return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; }
isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:
class Person{ private Date birthDate; private static Date startDate,endDate; static{ startDate = Date.valueOf("1946"); endDate = Date.valueOf("1964"); }
public Person(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; }
因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行
静态初始化块可以置于类中的任何地方,类中可以有多个静态初始化块。 在类初次被加载时,会按照静态初始化块的顺序来执行每个块,并且只会执行一次。
static关键字的误区 static关键字会改变类中成员的访问权限吗?
有些初学的朋友会将java中的static与C/C++中的static关键字的功能混淆了。在这里只需要记住一点:与C/C++中的static不同,Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字。看下面的例子就明白了:
public class Person {
public String name = "李四"; private static String address = "中国";
说明static关键字不能改变变量和方法的访问权限
能通过this访问静态成员变量吗?
public class Main { static int value = 33;
public static void main(String[] args) throws Exception{ new Main().printValue(); } private void printValue(){ int value = 3; System.out.println(this.value); }
这段代码输出结果为:33
this代表什么?this代表当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是33。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
static能作用于局部变量么?
static是不允许用来修饰局部变量。不要问为什么,这是Java语法的规定
static常见笔试面试题 1、下面这段代码的输出结果是什么?
public class Test extends Base{ static{ System.out.println("test static"); } public Test(){ System.out.println("test constructor"); } public static void main(String[] args) { new Test(); } classBase{ static{ System.out.println("base static"); } public Base(){ System.out.println("base constructor"); } } }
输出结果为:
base static test static base constructor test constructor
分析下这段代码的执行过程:
找到main方法入口,main方法是程序入口,但在执行main方法之前,要先加载Test类
加载Test类的时候,发现Test类继承Base类,于是先去加载Base类
加载Base类的时候,发现Base类有static块,而是先执行static块,输出base static结果
Base类加载完成后,再去加载Test类,发现Test类也有static块,而是执行Test类中的static块,输出test static结果
Base类和Test类加载完成后,然后执行main方法中的new Test(),调用子类构造器之前会先调用父类构造器
调用父类构造器,输出base constructor结果
然后再调用子类构造器,输出test constructor结果
2、这段代码的输出结果是什么?
public class Test { Person person = new Person("Test"); static{ System.out.println("test static"); } public Test() { System.out.println("test constructor"); } public static void main(String[] args) { new MyClass(); } } class Person{ static{ System.out.println("person static"); } public Person(String str) { System.out.println("person "+str); } } class MyClass extends Test { Person person = new Person("MyClass"); static{ System.out.println("myclass static"); } public MyClass() { System.out.println("myclass constructor"); }
输出结果为:
test static myclass static person static person Test test constructor person MyClass myclass constructor
为什么输出结果是这样的?我们来分析下这段代码的执行过程:
找到main方法入口,main方法是程序入口,但在执行main方法之前,要先加载Test类
加载Test类的时候,发现Test类有static块,而是先执行static块,输出test static结果
然后执行new MyClass(),执行此代码之前,先加载MyClass类,发现MyClass类继承Test类,而是要先加载Test类,Test类之前已加载
加载MyClass类,发现MyClass类有static块,而是先执行static块,输出myclass static结果
然后调用MyClass类的构造器生成对象,在生成对象前,需要先初始化父类Test的成员变量,而是执行Person person = new Person("Test")代码,发现Person类没有加载
加载Person类,发现Person类有static块,而是先执行static块,输出person static结果
接着执行Person构造器,输出person Test结果
然后调用父类Test构造器,输出test constructor结果,这样就完成了父类Test的初始化了
再初始化MyClass类成员变量,执行Person构造器,输出person MyClass结果
最后调用MyClass类构造器,输出myclass constructor结果,这样就完成了MyClass类的初始化了
3、这段代码的输出结果是什么?
public class Test { static{ System.out.println("test static 1"); } public static void main(String[] args) { } static{ System.out.println("test static 2"); }
输出结果为:
test static 1 test static 2
抽象类
//abstract抽象类:类extends:单继承~(接口可以多继承) public abstract class Action { //约束~有人帮我们实现~ //abstract ,抽象方法,只有方法名字,没有方法的实现! public abstract void doSomething(); //1.不能new这个抽象类,只能靠子类去实现它;约束! //2.抽象类中可以写普通的方法 //3.抽象方法必须在抽象类中 //抽象的抽象:约束~ //思考题?new ,存在构造器么? //存在的意义抽象出来、提高开发效率 }
即使你没有提供任何构造函数,编译器将为抽象类添加默认的无参数的构造函数,没有的话你的子类将无法编译,因为在任何构造函数中的第一条语句隐式调用super()。
扩展 有抽象方法的类一定是抽象类
是抽象的类不一定要有抽象方法
无法通过new实例,通过继承
子类必须实现所有的父类抽象方法,否则也要注明abstract
接口
1、什么是接口? 接口一般来讲分为两种:
(1)程序内部的接口:方法与方法、模块与模块之间的交互,程序内部抛出的接口,如登录发帖,发帖就必须要登录,如果不登录不能发帖,发帖和登录这两个模块之间就要有交互,就会抛出一个接口,进行内部系统调用。
(2)系统对外的接口:从别人的网站或服务器上获取资源或信息,对方不会提供数据库共享,只能提供一个写好的方法来获取数据,如购物网站和第三方支付之间,购物网站支付时可选择第三方支付方法,但第三方不会提供自己的数据库给购物网站,只会提供一个接口,供购物网站进行调用。
2、接口的分类?
接口分类一般分为两种:
(1)webService接口:走soap协议通过http传输,请求报文和返回报文都是xml格式的。测试时需要通过工具才能进行调用、测试。少数公司还在使用这种接口,如医院等行业。
(2)http api接口:走http协议,通过路径来区分调用的方法,请求和报文都是key-value形式的,返回报文一般都是json串,有get和post等方法。目前来讲,是最常用的。
3、接口返回数据
接口返回的数据一般都是json串,json是一种通用的数据类型,格式为key-value。
4、前端、后端区别? 前端:客户端。通俗来讲,一般情况下,web端或app端能看见的地方以及一些简单的校验,都属于前端。
(ps:网站上显示的后台管理不属于后端哦)
后端:服务器端。web端或app端的系统逻辑、如购物时扣除余额,微博发到哪里等都是由后端实现的。
//抽象类:extends //接口:implments //实现接口的类必须重写接口的方法 //利用接口能实现多继承 public class UserserviceImpl implements Userservice,Timeservice { @Override public void add(String name) { } @Override public void delete(String name) { } @Override public void update(String name) { } @Override public void query(String name) { } @Override public void timer() { } }
//interface定义的关键字,接口都需要有实现类 public interface Userservice { //常量 public static final int p=3; //接口中的所有定义的方法其实都是抽象的public abstract void add(String name); void delete(String name); void update(String name); void query(String name); }
public interface Timeservice { void timer(); }
作用:
-
约束
-
定义一些方法,让不同的人实现~10--->1。
-
public abstract(抽象方法)。
-
public static final(常量)。
-
接口不能被实例化,接口中没有构造方法。
-
implements可以实现多个接口。
-
必须要重写接口中的方法。
内部类
静态内部类:
当在静态内部类里访问外部类的静态数据成员是没有问题的,但是如果访问外部类的实例数据成员时,就会报错
public class TestDemo2 { //静态内部类 public static void main(String[] args) { //InnerClass in2 = new InnerClass();//不要这样写,会报错! OuterClass.InnerClass in = new OuterClass.InnerClass(); in.show2(); }
那么静态内部类如何访问外部类的实例成员变量? 1.因为实例成员变量依赖于外部类的对象 2.能否传入一个外部类对象(由构造函数传入) 3.主函数内实例化一个外部类对象OuterClass outer = new OuterClass(); 4.在内部类的构造函数传入一个外部类的实例成员变量 OuterClass o2; 5.接收外部类对象o2 6.o2已经拿到了外部类对象 7.System.out.println("a:"+o2.a);
static class InnerClass{ private int data1 = 10; private int data2 = 20; private int c = 100; private static int data3 = 30; OuterClass o2; public InnerClass(OuterClass o){//内部类的构造方法 o2 = o;//通过构造方法传入外部类对象 System.out.println("InnerClass init~~~~"); } public void show2(){ System.out.println("InnerClass show2()~~~~"); //System.out.println("a:"+a);//不可以访问外部类的成员,那怎么访问???? System.out.println("outerclass a:"+o2.a);//通过外部类对象来访问外部类的非静态数据成员 System.out.println("innerclass c:"+c); System.out.println("outerclass c:"+OuterClass.c);//外部类的c是静态的, //通过类名.数据成员来访问 System.out.println("d:"+d); }
匿名内部类:
相当于当前类的子类。
public class TestDemo3 { public static void test(Student s){ s.show(); } //匿名内部类,相当于当前类的子类 public static void main(String[] args) { new Student(){ public void show(){ System.out.println("niming show()~~~~"); } }.show(); /* test(new Student(){ public void show(){ System.out.println("niming show()~~~~"); } });*/ }
实例内部类
public class Outer { private int id = 20; public void run() { System.out.println("这是一个外部类"); } public class Inner { public void go() { System.out.println("这是一个内部类"); } //获得外部类私有属性和方法 public void getID(){ System.out.println(id); } } }
public class Application { public static void main(String[] args) { Outer outer=new Outer(); //通过外部类来实例内部类 Outer.Inner inner=outer.new Inner(); inner.go(); inner.getID(); } }
本地内部类
在方法内部的类
//本地内部类,在方法内部的类 public void test(){ final int data6 = 10;//局部变量 class InnerClass{ private int a = 10; //private static int b = 20;//报错 private static final int c = 30;//编译期间所确定的立即数 public InnerClass(){ System.out.println("test() InnerClass Init~~~~"); } public void show(){ System.out.println("a: "+a); System.out.println("c: "+c); System.out.println("data6: "+data6); System.out.println("test() show~~~~"); } } InnerClass in = new InnerClass(); in.show(); }
异常机制
-
异常指程序运行中出现的不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。
异常发生在程序运行期间,它影响了正常的程序执行流程。
-
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。 运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。 错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
error
Error类对象由Java虚拟机生成并抛出大多数错误与代码编写者所执行的操作无关。 Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时、Java虚拟机(JV)一般会选择线程终止; 还有发生在虚拟机试图执行应用时,如类定义错误NolassDefFoundError)、链接错误(LinkageError),这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
Error和Exception的区别:
Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
异常处理机制
抛出异常
捕获异常(五个关键字try catch finally throw throws)
public static void main( String[] args) { int a = 1; int b = e; //假设要捕获多个异常:从小到大! try{ //try监控区域 system.out.println(a/b); } catch (Error e){ //catch(想要捕获的异常类型!)捕获异常 system.out.print1n(IError"); } catch(Exception e){ system.out.println( "Exception" ); } catch (Throwable t){ system. out.print1n("Throwable"); } finally{ //处理善后工作 system.out.println( "finally"); } //finally 可以不要finally,假设I0,资源,关闭! public void a(){ b(); } public void b(){ a(); } }