Java笔记
记事本开发步骤:
1.编写java文件
2.编译java文件,生成class文件
3.运行class文件
4.输出结果
- .class 字节码文件
- 先将java文件编译成字节码文件
注释:
//单行注释
/*加回车,多行注释
/**加回车,文档注释,用于详细说明,可以生成文档说明书
换行
换行是因为println
可以输出system.out.print("eee\n");==system.out.println("eee");
java编译
java编译是通过虚拟机JVM进行编译解释的,java是半编译半解释
项目导入、导出
项目导出
选择项目右键,点击export,选择General文件下File System文件,再选择导出路径
或者直接Ctrl+c,Ctrl+v,复制粘贴(项目大时有可能丢失文件)
项目导入
空白区域右键,选择Import,选择General文件下Exiting Projects into Workspace,再选择想导入项目的路径
编码格式
windows中preference中设置workspace的utf-8编码格式,中文兼容性强
字符
关键字:对于编译器来说有特殊含义的单词(红色的字)
保留字:已经被java征用,但是还没有具体含义的单词,比如goto
标识符:像类名,方法名,变量名,包名等(凡是自己起名字的地方)
标识符命名规则:数字,字母,下划线,¥,其中数字不能开头
标识符命名规范:
类名:每个单词首字母大写;
方法名,变量名:一个单词首字母小写,多个单词,第一个单词首字母小写,剩下每个单词首字母大写,例如:shouName
包名:每个字母都小写,中间可以用.分割
常量名:所有字母都大写
转义字符:
System.out.println("你好\"中国\"");——输出:你好”中国“
\r 表示接受键盘输入,相当于按下了回车键
\n 表示换行
\t 表示制表符Tab键
\b 表示退格键,相当于Backspace
\' 相当于单引号'
\" 相当于双引号"
\\ 表示一个斜杠\
数据类型
数据类型:
基本数据类型:整数类型:byte short int long(书写特殊,后面需要加L)
浮点类型:float(书写特殊,后面需要加f或F) double
字符类型:char(单引号中只能有一个字符)
布尔类型:boolean(只能是true或者false)
引用数据类型:类、数组、接口
整数类型:
类型 占用存储空间 表数大小
byte 1字节 -128~127
short 2字节 -2^15~2^15-1
int 4字节 -2^31~2^31-1
long 8字节 -2^63~2^63-1
浮点类型:
float 32位 -3.403E38~3.403E38
double 64位 -1.798E308~1.798E308
字符类型:
char 16位 0~65535
布尔类型:
boolean b1 = false;
system.out.println(b1);
输出结果为:false
数据类型转换
数据类型转换:byte\short\int\long\float\double(默认int)
类型转换:小类型->大类型
byte b1 = 3; int b2 = b1;(byte转换成int型)
强制类型转换:大类型->小类型
byte b3 = (byte)b2;(将b2强制转换为byte型)
进制
十进制:0~9 第一位不能是0;
十六进制:0~9 A~F 必须以0X或者0x开头
八进制:0~7 必须以0开头
二进制:0 1 JDK7以后的版本,必须以0b或者0B开头
运算符
赋值运算符:=,+=,-=,*=,/=,%=
算术运算符:+,-,*,/,%,++,--
比较运算符:>,<,>=,<=,==,!=
逻辑运算符:!,&&,||
条件运算符:?:
条件表达式?值1:值2;(表达式为真执行左边的值1,表达式假的执行右边值2)
&&和&的区别:(面试题)
&&:逻辑运算符,只能参与逻辑运算,具有短路效应,开发常用。
&:按位运算符,能参与逻辑运算还能参与按位运算,不具备短路效应,开发不常用。(将数字转换成二进制)
短路效应:当符号左面表达式的结果可以作为整个表达式的结果,符号右面就不用执行了。
一元运算符:只有一个操作数的符号 例:+3 a++ --6
二元运算符:有两个操作数的符号 例:a+b
三元运算符:表达式 ?值1:值2
条件表达式
if条件表达式:
if(){};
else if(){};
else{};
swicth表达式:switch(表达式){ //表达式进行判断,与case值相等则进行该case后面的运算
case 值:代码;
break;
case 值:代码;
break;
default:代码;
break;
}
输入语句
方式一:
int a = new Random().nextInt(10)+1;
方式二:
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();//输入整数
输入一个随机数:
int a = new Random().nextInt(12);//随机数范围是0-11
int a = new Random().nextInt(12)+1;//随机数范围是1-12
循环中断机制
* break;用于结束整个循环
* continue;用于结束本轮循环,进入下一轮循环
debug 找断点,可调式程序。
循环嵌套语句
死循环:不能自身终止的循环称为死循环,它不是错误,只是另一种形式。
dowhile的死循环:
do {
System.out.println("qqq");
}while(true);
while的死循环
while(true) {
System.out.println("ppp");
}
for的死循环:
for ( ; ; ) {
//for(int a = 0;true;a++)也对
System.out.println("ooo");
}
数组
数组:可以看作一个容器,能够存放任意类型的数据,数组长度一经定义不可改变
如何定义数组:
* 按照长度定义:
1.先声明再赋值:数据类型 【】 数组名; 数组名 = new 数据类型【长度】
int[] arr; arr = new int[3];
2.声明并且赋值:数据类型 【】 数组名 = new 数据类型【长度】
int[] arr2 = new int[3];
* 按照内容定义:
1.数据类型【】 数组名 = {值,值,值。。。}
2.数据类型【】 数组名 = new 数据类型【】{值,值,值。。。}
数组名【索引】 = 值;
索引就是下标,从0开始。
foreach遍历数组==for循环遍历数组
for(int:arr5){
System.out.println(x);
}//按序输出数组的每一个值
字符数组比较
数组字符串比较:str.equals();
String s = "abc";
System.out.println(s.equals("abc"));
相等返回true,不等返回false;
内外层循环
循环标号:可以在内层循环结束外层循环
outer: for(int i = 0;i < 10;i++) {
System.out.println("outer loop");
inner: while(true) {
String j = new Scanner(System.in).next();
System.out.println("inner loop:" + j);
if(j.equals("hello")) {
break inner;
}
if(j.equals("kitty")) {
break outer;
}
}
局部变量和属性(全局变量、成员变量)的区别
1.位置不同:属性在类里方法体外,局部变量在方法体或代码块里
2.生命周期不同:属性随着类结束而结束,局部变量随着所在方法结束而结束
3.属性属于对象,局部变量属于方法
4.属性有默认值,局部变量没有默认值,需要声名并且赋值才可以用
方法
定义方法(4种方式)有两个明确:
1、返回值类型---有两种---void(没有返回值)----数据类型(有返回值)
2、参数---有参数---无参数
方法调用:
数组存储和堆内存有关
方法重写
方法重写:(继承、实现)
方法名一样
参数一样
返回值类型一样
子类方法的访问修饰符不能缩小访问权限
方法重载
方法重载:
方法名相同
参数列表不同(个数不同、类型不同、顺序不同) (参数看类型,不看名字)
与返回值类型无关
封装、继承、多态
封装:
1.将属性私有化,使用private关键字修饰。
2.为使用private关键字修饰的属性添加getter和setter方法。通过get和set方法来操作属性。
3.在setter方法中,添加数据的逻辑校验。
继承:
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
如果某类B“继承”另某类A,就把这个B称为“A的子类或派生类(subclass)”,而把类A称为“B的父类”也可以称为“A是B的超类或基类(superclass)”
继承的语句格式:
[权限修饰符] class 子类名 extends 父类名{}
多态:
定义:多态就是父类引用子类对象。 向同⼀个父类的不同子类发送同⼀条消息,行为不同
如何实现多态:
1.继承:子类继承父类
2.重写:子类方法重写父类方法
3.向上转型:父类引用指向子类对象
4.调用父类被重写的方法时,不同的子类效果不同
编译期都看父类
执行期分情况:
1.属性,看父类(多态发生时,属性看父类初始值)
2.方法,看子类
if (p instanceof student)//用于
((student).p).play()
- 静态不能直接访问非静态
- 向下转型的目的:访问子类特有成员。
类和对象的关系
is...a 继承
has...a 属性、方法
use...a 参数
new:调用构造函数返回一个对象
访问权限
private:本类
默认的(default)本包
protected:本包及外包子类
public:本项目
能修饰类的访问权限只有public和default
代码块
1.静态代码块:初始化静态变量,类加载的时候,加载了静态代码块,静态代码块只加载一次
2.构造代码块:初始化成员变量,创建对象得时候优先构造方法执行,创建几次对象,就会执行几次代码块
3.局部代码块:定义在方法中,只执行一次,会按照代码执行顺序执行
4.代码块执行顺序:静态代码块最优先执行,构造代码块和局部代码块取决于代码的执行顺序
内存
栈内存:
引用类对象地址,基本数据类型
堆内存:
保存各种属性
引用类型‘==’是比较地址
在str1创建“helloWorld”时,字符串内存地址存在字符串常量池中,str2是用new的方式创建字符串对象,被new创建的对象会在堆内存中开辟一个空间存放,两个对象内存地址不相同
new 的东西都放在堆里
原生equals方法比较地址
toString能把equals方法重写
equals方法强制转换(是Object类的方法)
例子:
public class Student {
String name;
int age;
String sex;
//重写一个
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if(((Student)obj).name==this.name&&((Student)obj).age==this.age) {
return true;
}
return false;
}
}
Object类
Object类是所有类的父类
类中的方法
1.equals 原生的equals与==相同,比较的是两个对象的值,返回一个boolean类型
equals方法主要用于object子类进行重写
2.hashCode返回对象的hash值
3.hashCode和equals关系
1.如果重写了equals,那么要求hashCode必须重写,保证对象的唯一性。
2.如果两个对象hashCode相同,那么两个对象的equals不一定相同
包装类
包装类:
包装类一共有8个,对应8种基本数据类型
基本数据类型:byte,short,int,long,float,double,char,boolean
引用数据类型·:Byte,Short,Integer,Long,Float,Double,Character,Boolean
打包和拆包:
打包:将基本数据类型打包成一个引用类型
拆包:将引用数据类型拆解成基本类型
几乎所有的数据类型都有parade,除了character
String、StringBuffer、StringBuilder类
String类 字符串类 是一个final修饰的类
不可变字符串,所有的方法都产生新的String而存在的,不会改变之前的字符串。
StringBuffer类:
可变字符串,多线程,且线程安全,效率略低,只能使用构造器赋值
StringBuilder
可变字符串,单线程,线程不安全,效率高,只能使用构造器赋值
常见类
Math数学类
提供了很多数学领域的函数
Random随机类
提供了获取下一个随机数的方法,该种随机是一种伪随机,是一种通过种子数(seed)进行计算的随机
Date日期类:
提供了两个构造器
无参构造代表当前系统的日期
带参构造代表距1970年1月1日0时0分0秒后毫秒的时间
DateFormat
日期格式化类
是一个抽象类,通过getDateInstance/getTimeInstance/getDateTimeInstance获取对象
DateInstance只能获取一个Data的日期
TimeInstance只能获取一个Date的时间
DateTimeInstance能获取完整的日期和时间
format方法是将一个Date转成一个String
parse方法是将一个Sting转成一个Date
SimpleDateFormat自定义获取的时间的格式
Calendar类
可以
system类
输入流、输出流、错误流
数组复制
手动垃圾回收:System.gc();
退出虚拟机:System.exit(0);
内部类
内部类:
一个类中,存在成员,成员包括了成员变量(属性)、成员方法、成员内部类
成员内部类本质上和成员变量、成员方法同级
四种访问权限都可以修饰内部类
成员内部可以访问本类成员、外部类成员、外部类私有成员
创建内部类对象,必须指明当前内部类所在的外部类
在非静态内部类中,是不允许出现静态成员,如果出现了静态成员,需要这个内部类是一个静态类
静态内部类中可以存在静态成员
局部内部类
定义在方法中的一个内部类,随着方法的执行而执行
枚举,类似于单选
抽象类和接口的区别
接口,抽象类
1.名字不同
2.属性:抽象类有属性,接口,静态常量
3.方法:抽象类可以没有抽象方法,接口中必须用public,abstract
4.构造方法,抽象类有,接口没有
5.类-类:单继承,类-接口多实现,接口-接口:多继承
6.抽象类子类:派生类;接口子类:子实现类
异常
常见的异常:
1.数组下标越界异常 ArrayIndexOutOfBoundsException
2.空指针异常 NullPointerException
3.算数异常 ArithmeticException
4.类型转换异常:ClassCastException
5.数字格式化:NumberFormatException
6.解析异常 :ParseException
异常分类:
1.异常:Exception 在程序运行过程中可以解决的问题
2.错误:Error 在程序运行过程中不可解决的问题
Exception分类:
1.编译期异常
2.运行期异常
异常解决例子
public class ExceptionDemo {
//如果程序运行中出现了异常,那么程序会终止
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int seat = sc.nextInt();
String[] arr = new String[seat];
// arr[0] = "小明";//异常
try {
//可能发生异常的代码
arr[0] = "小明";
}catch(ArrayIndexOutOfBoundsException e) {
//catch(可能发生的异常类型的对象){解决异常的代码}
e.printStackTrace();//打印异常信息
}
System.out.println("解决完成");
}
}
解决异常的方式:
1.try..catch
try{
可能发生的异常的代码
}catch(发生异常类型的对象1|发生的异常类型对象2 ){
解决方式;
}
2.多个catch块向下添加
try{
可能发生的异常的代码
}catch(发生异常类型的对象1 ){
}catch(发生的异常类型对象2){
}...
需要注意的是,更大的Exception要放在后面,Exception等级从小到大。
如果一段代码发生了异常并且进行了捕获(catch),那么这段代码不会再执行try里面的程序
3.try..catch..finally
try{
可能发生的异常的代码
}catch(发生异常类型的对象1|发生的异常类型对象2 ){
}finally{
无论是否捕获都会执行的代码
}
例子:
public class FinallyDemo {
public static void main(String[] args) {
int[] arr = new int[0];
try {
arr[0] = 10;
return;
//在try中return,会得到"finally,解决完成"
}catch(ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
// return;
//在catch中return,会得到"finally"
}finally {
//无论是否捕获都会执行的代码
System.out.println("finally");
}
System.out.println("解决完成");
}
}
注意,try和catch中的return都不能阻止finally的执行,只有System.exit(0);可以(退出程序)
4.try..finally
异常的解决方式二:
throw + throws
throw:在方法体中,抛出的是一个·异常对象
throws:在方法声明时,抛出的是一个异常类,可以同时向上抛出多个异常,使用逗号分隔
在throw的时候,最终只能抛到main方法处,就必须要使用try...catch进行解决
例子:
package com.wx.demo;
import java.util.Scanner;
public class shuaiguoDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
int j =sc.nextInt();
// show();要想调用show(),需要解决show抛出的异常
// 调用cal方法
// try {
// cal(i,j);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
System.out.println("计算完毕");
}
public static void cal(int num1,int num2) throws Exception{
//加减乘除
if(num2==0) {
//向调用者抛出一个对应的异常对象,希望调用者协助解决问题
//如果在方法体中,throw了一个异常对象,那么需要在方法声明处,throws对应的异常类
throw new Exception();
// throw new ArithmeticException();
}else {
System.out.println(num1/num2);
}
}
public static void show() throws Exception {
//当有人调用show(),show()将异常抛给调用者
cal(1,0);
}
}
如果向上抛出的是一个运行期异常,那么可以不解决,也可以不抛出
如果向上抛出的是一个编译器异常,那么必须要throws,并且必须要解决
解决时的异常不能比抛出时候小
集合
集合是一种容器,同数组不同,集合可以在使用中动态调整容量
集合的分类:
1.collection 单列集合
collection分类:
1.list
a.ArrayList 底层的结构是数组,存取有序,先存先取,优势在与查询效率高
b.LinkedList 底层结构是链表,存取有序,先存先取,优势在于增删效率高
c. vector 底层是数组,查询和增删都慢
2.set
a.HashSet 底层结构是哈希表,无序,值不可以重复,存储自定义类型对象的时候,需要重写这个类中
b.TreeSet 底层结构式二叉树
2.map 存储的都是键值对的映射关系
泛型:
可以修饰一个类或者方法,表示一种规范或者约束
如果不添加泛型,那么该类的泛型为Object
toCharArray()
将此字符串转换为新的字符数组