目录
本篇文章仅记录在学习SE中遇到的问题哈~
数据类型与变量
数据类型 | 关键字 | 内存占用 | 范围 |
字节型 | byte | 1字节 | -128~127 |
短整型 | short | 2字节 | -32768~32767 |
整型 | int | 4字节 | |
长整型 | long | 8字节 | |
单精度浮点数 | float | 4字节 | |
双精度浮点数 | double | 8字节 | |
字符型 | char | 2字节 | |
布尔型 | boolean | 没有明确规定 |
1、boolean和int类型不能相互转换,不存在1表示true,0表示false
2、可以通过MAX_VALUE、MIN_VALUE来查看数据类型的最大值、最小值,如下:
System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.MAX_VALUE);
3、上述八种数据类型与String的区别:
这八种是基本数据类型,而String是引用数据类型。
数据类型分为基本数据类型和引用数据类型:
- 基本数据类型:八种
- 引用数据类型:String、数组、类、接口
4、java局部变量使用的时候必须初始化,否则报错。
5、在运算的过程中,所有小于4字节的会提升为4字节进行运算,如下:
byte a=10;
byte b=20;
byte c=a+b; //这里会报错,需要进行显示类型转换
因为计算机CPU通常是按照4个字节为单位从内存中读取数据,所以会将小于4字节的会提升为4字节。
6、java中字符串类型,不是以“\0”当作字符串的结尾。底层是一个数组,所以不需要。
7、int转String
int num=10;
//方法1
String str1=num+"";
//方法2
String str2=String.valueOf(num);
8、String转int
String str=“100”;
//方法1
int num=Integer.parseInt(str);
//方法2
int num=Integer.valueOf(str);
Java获取输入
Scanner scanner=new Scanner(System.in);
System.out.println("请输入你的姓名:");
String name=scanner.nextLine();
System.out.println(name);
System.in表示从键盘获取
有时候,需要循环判断是否还有输入,因此,我们可以通过hasNext()方法进行判断,再读取,如下:
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext())
{
String t=scanner.nextLine();
System.out.println("读取到的数据:"+t);
}
当循环输入多个数据的时候,可以使用ctrl+z来结束输入 ,再Linux/Mac使用ctrl+d。
随机数
Random random=new Random(); //这里如果不填入参数,使用当前时间为随机种子
int t=random.nextInt();
方法重载
- 方法名必须相同
- 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
- 与返回值类型是否相同无关
同一个作用域中不能定义两个相同名称的标识符,比如:方法中不能定义两个名字一样的变量,那为什么类中可以定义方法名相同的方法呢?
通过方法签名即:经过编译器编译修改过之后方法最终的名字。具体的方式:方法全路径名+参数列表+返回值类型,构成方法完整的名字,例如:
int add(int,int) 真正的名字是:add:(II)
double add (double,double)真正的名字是:add:(dd)
数组
定义
方法一:
int [ ] array={1,2,3};
方法二:
int [ ] array=new int [ ] {1,2,3};
- 该方法与方法一一样
- 如果不进行初始化 int [ ] array=new int [10],默认会初始化为0,10可以换成变量;
获取长度
int len=array.length;
遍历数组
int[] array=new int[10];
for(int x:array)
{
System.out.println(x);
}
在Java中,数组有一个工具类Arrays。
工具类Arrays
将数组转成字符串
int[] array=new int[10];
- for(int i=1;i<=10;i++)
{
array[i-1]=i;
}
System.out.println(Arrays.toString(array)); //一维数组System.out.println(Arrays.deepToString(ret));//二维数组
将数组排序
int[] array=new int[10];
Arrays.sort(array);
sort支持区间排序,比如:
Arrays.sort(array,0,2);
- 表示将[0,2)区间元素排序
拷贝数组
int[] ret=Arrays.copyOf(array,array.length);
- copyOf方法返回一个数组对象
- 第一个参数是要拷贝的数组
- 第二个参数是拷贝的长度
当然我们也可以进行区间拷贝
int[] ret=Arrays.copyOfRange(array,0,3);
- 拷贝array数组[0,3)范围的元素
在定义二维数组时,行不能省略,列可以省略
类和对象
类名使用大驼峰定义
每个类会产生一个字节码文件,跟java文件没有关系。
成员变量在没有初始化的时候,都会有一个默认值:
- 引用类型默认值都是null
- int 0
- float 0.0f
- boolean false
- char ‘\u0000’
关于生成构造方法、get方法、set方法可以使用generate自动生成
封装
包
包就是为了更好的组织和管理类,比如Arrays 专门组织管理和操作数组相关的类
包是对类、接口等的封装机制的体现,是一种对类或者接口等很好的组织方式,包还有一个很重要的作用,在同一个工程中允许存在相同名称的类,只要处在不同的包即可
private | default(包访问权限) | protected | public | |
同一包中的同一类 | ||||
同一包中的不同类 | ||||
不同包中的子类 | ||||
不同包中的非子类 |
静态方法的特性
- 不能在静态方法中访问任何非静态成员变量
- 静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
- 静态方法无法重写
静态代码块
用来初始化静态变量,类加载的时候就被调用了,只执行一次
static{
……
}
构造代码块/实例代码块
{
……
}
类被实例化的时候调用。实例化一个调用一次
super和this的相同点:
只能在类的非静态方法中使用,用来访问非静态成员方法和字段
在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
多态的条件
- 继承关系向上转型,父类引用子类
- 子类和父类有同名的 覆盖/重写方法
- 通过父类对象的引用,去调用这个重写的方法
完成以上部分
在继承的关系上,满足以下三点:
- 方法的返回值一样
- 方法名一样
- 方法的参数列表一样
那么就说这两个方法之间的关系是重写
重写和重载的区别
区别点 | 重写 | 重载 |
参数列表 | 一定不能修改 | 必须修改 |
返回类型 | 一定不能修改(除非可以构成父子类关系) | 可以修改 |
访问限定符 | 一定不能做更严格的限制(可以降低限制) | 可以修改 |
判断一个引用对象是某个对象的实例可使用instanceof来进行进行判断。
抽象类
特性
- 抽象类不能直接实例化对象
- 抽象方法不能是private
- 抽象方法不能被final和static修饰,因为抽象方法要被子类重写
- 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用abstract修饰
接口
接口是一种引用数据类型
- 接口是使用interface方法来修饰的
- 接口当中不能有被实现的方法,意味着只能有抽象方法,但是两个方法除外:一个是static修饰的方法,一个是被default修饰的方法,static意味着不能被重写,deffault方法可以重写,如果不重写就使用默认的
- 接口当中的抽象方法默认都是public abstract修饰的
- 接口当中的成员变量默认都是public static final修饰的
- 接口不能进行实例化
- 类和接口之间的关系,可以使用implements来进行关联
- 接口中不能有静态代码块和构造方法
语法规则
定义接口
public interface 接口名称{
//抽象方法
}
TIPS:
- 创建接口时,接口的命名一般以大写字母I开头
- 接口的命名一般使用“形容词”词性的单词
接口的使用
接口不能直接使用,必须有一个“实现类”来实现该接口,实现接口中的所有抽象方法。
public class 类名称 implements 接口名称{
……
}
Comparable
让一个类可以进行比较,需要实现 Comparable中compareTo方法
//Comparable<进行比较的类型>
class Student implements Comparable<Student>{
public Student(String name, int age) {
this.name = name;
this.age = age;
}String name;
int age;
@Override
public int compareTo(Student o) {
if(age<o.age)
return 1;
else
return 0;//compareTo返回整型而不是布尔类型
}
}public class Main {
public static void main(String[] args) {
Student s1=new Student("张三",20);
Student s2=new Student("李四",21);
System.out.println(s1.compareTo(s2));}
}
但是这种方法,后期如果需要对类比较的属性进行变动不太方便,因此还需要使用其他方法。
Comparator比较器
class Student{ public Student(String name, int age) { this.name = name; this.age = age; } String name; int age; } class AgeComparator implements Comparator<Student>{ @Override public int compare(Student o1, Student o2) { return o1.age-o2.age; } } public class Main { public static void main(String[] args) { Student s1=new Student("张三",20); Student s2=new Student("李四",21); AgeComparator ageComparator=new AgeComparator(); System.out.println(ageComparator.compare(s1,s2)); } }
Object类
object是Java默认提供的一个类,java里面除了Object类,所有的类都是存在继承关系的,默认会继承Object类,即所有类的对象都可以使用Object的引用进行接收。
对象比较方法
在java中,==进行比较时:
- 如果==左右两侧都是基本类型变量,比较的是变量中值是否相同
- 如果==左右两侧都是引用类型变量,比较的是引用变量地址是否相同
- 如果要比较对象中内容,必须重写Object中的equals方法,因为equals默认也是按照地址来比较的
内部类
将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类,内部类也是封装的一种体现。
内部类不能创建静态成员,如果一定需要使用static修饰,需要再添加const修饰。
实例内部类
创建一个内部类对象的方法如下:
class Student{
public Student(String name, int age) {
this.name = name;
this.age = age;
}String name;
int age;
class InnerClass{
public int id;}
}public class Main {
public static void main(String[] args) {
Student student=new Student("张三",10);
Student.InnerClass innerClass=student.new InnerClass();
}
}
在内部类中包含两个this
如果内部类和外部类有对象冲突的话,可以通过如下方法访问自己和外部类对象:
- 父类类型.this 访问父类对象
- this 访问内部类对象
小结
- 外部类中的任何成员都可以在实例内部类方法中直接访问
- 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
- 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名.this.同名成员 来访问
- 实例内部类对象必须在先有外部类对象前提下才能创建
- 实例内部类的非静态方法中包含了一个指向外部类对象的引用
- 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类对象
静态内部类
静态内部类创建时,不需要先创建外部类
在静态内部类中,只能访问外部类中的静态成员
String类
比较
判断两个String是否相等,不能直接使用等号,因为使用等号会直接比较地址,需要使用equals方法:
String s1=new String("hello");
String s2=new String("hello");
System.out.println(s1.equals(s2));
如果需要对两个字符串按字典序比较的话使用compareTo方法
String s1=new String("abc");
String s2=new String("abd");
System.out.println(s1.compareTo(s2)); //-1:s1比s2小 , 0: s1和s2相等....
如果需要在比较的时候忽略大小写,则使用compareToIgnoreCase方法
String s1=new String("abc");
String s2=new String("Abc");
System.out.println(s1.compareToIgnoreCase(s2));
查找
获取String字符串的某个字符 charAt(下标)
String s1=new String("abc");
System.out.println(s1.charAt(1));
方法 | 功能 |
---|---|
char charAt(int index) | 返回index位置上字符,如果index为负数或者越界,抛出异常 |
int indexOf(int ch) | 返回ch第一次出现的位置,没有返回-1 |
int indexOf(int ch,int fromindex) | 从fromindex位置开始找ch第一次出现的位置,没有返回-1 |
int indexOf(String str) | 返回str第一次出现的位置,没有返回-1 |
int indexOf(String str,int fromindex) | 从fromindex位置开始找str第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch) | 从后往前找,返回ch第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch,int fromindex) | 从fromindex位置开始找,从后往前找ch第一次出现的位置,没有返回-1 |
int lastIndexOf(String str) | 从后往前找,返回str第一次出现的位置,没有返回-1 |
int lastIndexOf(String str,int fromindex) | 从fromindex位置开始找,从后往前找str第一次出现的位置,没有返回-1 |
大小写转换
String s1=new String("abc");
String s2=s1.toUpperCase();
System.out.println(s1);
System.out.println(s2);
需要注意的是,转变大小写,不是在原来的基础上转变,而是产生一个新的对象
格式化
String s=String.format("%d-%d-%d",1,2,3);
System.out.println(s);
数组和字符串转换
字符串转数组
String s1=new String("abc");
char[] ch=s1.toCharArray();
数组转字符串
String s2=new String(ch);
替换
方法 | 功能 |
---|---|
String replaceAll(String regex,String replacement) | 替换所有的指定内容 |
String replaceFirst(String regex,String replacememt) | 替换首个匹配内容 |
字符串拆分
方法 | 功能 |
---|---|
String[] split(String regex) | 将字符串全部拆分 |
String[] split(String regex,int limit) | 将字符串部分拆分,该数组长度就是limit极限 |
注意事项:
- 字符“|”,“*”,“+”都得加上转义字符,前面加上“\\”
- 而如果是“\”,那么就得写成“\\\\”
- 如果一个字符串中有多个分隔符,可以用“|”作为连字符
字符串截取
方法 | 功能 |
---|---|
String substring(int beginIndex) | 从指定索引截取到结尾 |
String substring(int beginIndex,int endIndex) | 截取部分内容 |
String、StringBuffer、StringBuilder的区别
String的内容不可修改,StringBuffer与StringBuilder的内容可以修改
StringBuffer与StringBuilder大部分功能是相似的
StringBuffer采用同步处理,属于线程安全操作,而StringBuilder未采用同步处理,属于线程不安全操作
异常体系结构
Throwable:是异常体系的顶层类,其派生出两个重要的子类:Error和Excepion
Error:指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误,资源耗尽等
Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行。
异常分为:
- 运行时异常(非受查异常)
- 编译时异常(受查异常)
异常的处理
防御型编程
EAFP,事后认错型(try-catch)--异常处理的核心思想。
异常的抛出
抛出异常的方式有很多种:
- 某段程序触发
- 通过关键字throw抛出异常
TIPS:
- throws一般使用现在方法的声明之后,告诉调用这个方法的人:这个方法可能会抛出异常
- try块内抛出异常位置之后的代码将不会被执行
- 虽然可以捕获多种异常,同一时刻只会抛出一个异常
- finally里面的代码一定会被执行,即使前面有return,常用来释放资源
- 如果finally有return,那么就不会执行try里面的return,会执行finally里面的return
throw和throws的区别?
throw是扔出一个异常,而throws是在方法声明一个异常
自定义异常
如果需要自定义异常,一定要继承一个异常
- extends Exception 编译时异常
- extends RuntimeException 运行时异常