基本数据类型
java的类型转化:
强制类型转化:
大单位转化为小单位需要强制类型转化(+=,-=,/=,*=)自动进行强制类型转化
char和int的转化:char转化成为int,得到ascii码值,int 转化为char,得到ASCII码对应的字符
public static void main(String[] args) {
char a='a';
int b=a;
System.out.println(b);//97
a=(char)67;
System.out.println(a);// c
}
public static void main(String[] args) {
int a=10;
byte b=9;
char c=58;
//第一种 强制类型转化
// c =c+10;//会报错 ---
// +10表示加int类型,发生整形提示,转化成为int类型,而c是char类型,int-》char 大化小,需要强制类型转化
//第二种:自动类型转化 +=,*=,-=,/=发生自动类型转化 将得到的int类型转化为char类型
c+=10;//得到68对应字符
c-=10;
c*=10;
c/=10;
}
数据越界
public static void main(String[] args) {
byte a=127;
System.out.println(++a);
byte b=127;
b+=1;
System.out.println(b);
//得到的结果都是-128,
//127的补码:0111 1111 +1得到1000 0000 转化成为-128
}
final修饰变量
public static void main(String[] args) {
final byte a = 1,e=7;
byte b = 2, c = 9, d = 3;
//第一个:byte+byte的整形提升
// a = b + c;//错误
//1、b+c,两个byte类型之和,也会进行整形提升,得到int类型,而a是char类型 a =(char)(b + c)
// 2、哪怕进行了整形提升,a被final修饰,也不可以重新赋值
//第二个:成功
b= (byte) (c+a);
System.out.println(b);
}
运算符
除法和取模:有小数参与得到小数,符号看左边
public static void main(String[] args) {
System.out.println(1/1.0);// 1.0
System.out.println(1.0/1);//1.0
System.out.println(2.0%1);//0.0
System.out.println(1%1.0);//0.0
System.out.println(1/1);//1
System.out.println(-1/1);//-1
System.out.println(2%3);//2
System.out.println(-2%3);//-2
}
方法
静态方法和普通方法:普通方法内可以调用静态方法,静态方法不可以调用普通方法
静态方法和普通方法都可以重载
构造方法:
数组
c语言二维数组可以省略行,不可以省略列(连续的存储空间,自动补0)
java二维数组可以省略列,不可以省略行(空间不连续,先给行数组分配空间,不会自动补0)
类和对象
对于一个顶层类:修饰限定符是public 或者不写(一个java文件只会有一个public修饰的类,类名和java文件名相同)
其他:修饰限定符是public(公开) ,protected(子类访问),defalut(包访问),private(当前类)
class A{//外部类:只能是public 或者不写(默认default)
private class B{
}
protected class C{
}
public class d{
}
class m{
}
}
继承
java中一个类只可以继承一个父类,单继承
子类只能继承父类的公开属性
一个父类可以被多个类继承
final修饰的类不能被继承
执行顺序
class A{
static {
System.out.println("静态代码块");
}
{
System.out.println("实例化代码块");
}
public A(){
System.out.println("构造方法");
}
}
创建类的实例化对象,先会执行静态代码块,
其次是实例化代码块,构造方法
包含继承关系时
class A{
static {
System.out.println("父类静态代码块");
}
{
System.out.println("父类实例化代码块");
}
public A(){
System.out.println("父类构造方法");
}
}
class B extends A{
static {
System.out.println("子类静态代码块");
}
{
System.out.println("子类实例化代码块");
}
public B(){
System.out.println("子类构造方法");
}
}
实例化子类对象,结果是:
class C {
public C() {
System.out.println("c");
}
}
class A{
static {
System.out.println("父类静态代码块");
}
{
System.out.println("父类实例化代码块");
}
public A(){
System.out.println("父类构造方法");
}
}
class B extends A{
C c=new C();
static {
System.out.println("子类静态代码块");
}
{
System.out.println("子类实例化代码块");
}
public B(){
System.out.println("子类构造方法");
}
}
动态绑定:通过父类引用,引用被子类重写的方法,会调用子类方法
class Animal{
public String name="qiqi";
private int age=10;
public void s(){
System.out.println("ok");
}
}
class Bird extends Animal{
public void s(){
System.out.println("fine");
}
}
public static void main(String[] args) {
Animal a=new Bird();
a.s();
}
结果:fine
this和super关键字
super来访问父类属性
this访问类的属性(当前类)
两个都可以用来调用属性(变量,方法,构造方法)
this调用其余属性,优先在当前类查找,找不到会在父类查找,而this调用构造方法,只会在当前类查找
class Animal {
public String name="s";
int age=9;
}
class Bird extends Animal {
int age=91;
public void s(){
this.name="hi";//在当前类没有这个属性,在父类查找并更改
System.out.println(this.age);//91
System.out.println(this.name);//hi
System.out.println(super.age);//9
System.out.println(super.name);//hi
}
}
class Animal{
public Animal(){
System.out.println("父类的构造方法");
}
public Animal(int a,int b){
System.out.println("父类的带有参数的构造方法");
}
}
class Bird extends Animal {
public Bird(int a) {
System.out.println("子类带有参数的构造方法");
}
public Bird() {
//super()--- 创建父类对象,先会帮助父类构造,隐式调用没有参数的构造方法
// this(1);//调用子类带有一个参数的构造方法
super(1,2);//调用父类带有两个参数的构造方法
//this(1,2);--this只可以调用当前类的构造方法
System.out.println("子类的构造方法");
}
super和this的异同:
super在子类中使用,指向父类;而this指向当前类
- super.变量名,super.方法名(参数) ---在子类中调用父类的变量和方法
- this.变量名,this.方法名(参数)---优先在当前类中调用当前类的方法或变量,如果在当前类没有找到,如果这个类是子类,子类继承了父类的公开方法,this会在父类中进行查找
- super和this会调用构造方法:super(参数)在子类中可以调用父类的构造方法(必须是第一条语句) this(参数)会调用子类中符合要求参数类型的构造方法(必须是第一条语句)
- this和super都在构造方法中必须出现在第一行,不可以同时出现在构造方法中
- 每一个子类的构造函数都会引用父类的构造方法(父类含有无参的构造方法,会隐式调用,如果父类全是有参数的构造方法,必须显示调用)
- this和super都指向对象,不可以在静态环境使用
抽象类和接口
抽象类
被abstarct修饰的类
- 抽象类里的抽象方法没有方法体
public abstract void a();
- 抽象类不能被实例化
- 抽象类中可以包括普通成员
abstract class M {
public void print() {
}
private void a() {
}
//default void b(){};--不允许
void s() {
}
public static void l(){
}
}
- 抽象类是用来被继承的,不能使用final修饰
接口
特殊的抽象类,内部不含有普通方法(除非使用default或者static修饰)
- 接口内部的方法全部是public的
- 接口内部定义的变量由public static final 修饰,一定要初始化
- 接口不能被实例化,需要类来实现接口(使用implements关键字,重写接口的抽象方法)
final修饰符
1、用于修饰变量,这个变量无法更改
2、用于修饰方法,这个方法可以重载,无法重写
3、final修饰类,表示这个类不能被继承
final abstract static
- static修饰变量,方法和类(内部类)
- final修饰方法,变量和类
- abstract修饰类和方法,不可以修饰变量,抽象方法只可以在抽象类中
- 静态环境(static)不可以使用super或者this关键字
- abstract不可以和final,private,static共存:
- final和abstract共存修饰类:抽象类是用来被继承的,final修饰的类不能继承。
- final和abstract共存修饰方法:抽象方法是用来被重写的,final修饰的方法不能重写。
- private和abstract共存修饰方法:抽象方法是用来被重写的,private修饰的方法不能被子类访问。
- static和abstract共存修饰方法:抽象方法是用来被重写的,不可以直接访问,static修饰的方法属于方法区,可以直接访问。
String 比较是否相等
public static void main(String[] args) {
String str = "hello";
String ret = new String("hello");
System.out.println(ret == str);
System.out.println(ret.equals(str));
}
分析:hello在字符串常量池中创建成功,str指向了hello这个对象
String ret = new String("hello");创建时,会在字符串常量池中看是否有hello这个对象,发现有,那么将hello对象的引用赋值给变量
所以:
public static void main(String[] args) {
String str = "hello";
String ret = new String("hello");
//ret指向了新对象的引用 ==比较地址,不相等
System.out.println(ret == str);
//equals比较内容,相等 结果 true
System.out.println(ret.equals(str));
// 结果false true
String s="hello";
//s指向了和str的同一个对象, ==比较地址,相等
System.out.println(s == str);
//equals比较内容,相等 结果 true
System.out.println(s.equals(str));
String a="hel"+"lo";
//在编译时期,"hel"+"lo"转化为 hello,指向同一块对象
System.out.println(a == str);
//equals比较内容,相等 结果 true
System.out.println(a.equals(str));
String b=new String("hel")+"lo";
//在编译时期,"hel"+"lo"不能转化为 hello,不指向同一块对象
System.out.println(b == str);
//equals比较内容,相等 结果 true
System.out.println(b.equals(str));
}
Integer类比较是否相等
包装类和int比较
public static void main(String[] args) {
Integer b=new Integer (129);
int a=129;
System.out.println(a==b);
System.out.println(b.equals(a));
}
a==b:这时包装类会自动拆箱,转化成为int,值的比较
b.equals(a):值的比较
包装类和包装类的比较
public static void main(String[] args) {
Integer a=new Integer(2);
Integer b=new Integer(2);
//两个包装类类型的比较:比较地址,都是new一个地址,地址不相同
System.out.println(a==b);
//比较内容
System.out.println(b.equals(a));
//false true
}
public static void main(String[] args) {
Integer a=2;
Integer b= 2;
//两个包装类类型的比较:比较地址,【-128,127】存储在同一个数组中,指向同一个地址
System.out.println(a==b);
//比较内容
System.out.println(b.equals(a));
// true true
Integer c=-129;
Integer d=-129;
//两个包装类类型的比较:比较地址,-128~127存储在同一个数组中,-129不在范围之内,需要new对象,不指向同一个地址
System.out.println(c==d);
//比较内容
System.out.println(c.equals(d));
// false true
Integer e=-12;
Integer f=new Integer(-12);
//两个包装类类型的比较:比较地址,-128~127存储在同一个数组中,e指向了数组内的-12,f需要指向新的new对象,不指向同一个地址
System.out.println(e==f);
//比较内容
System.out.println(f.equals(e));
// false true
}
总结:包装类和int比较,==比较数字值是否相等
包装类和包装类的比较:==比较地址是否相等,【-128~127】内的数字,正常直接赋值,指向数组内的空间;new赋值,指向新的对象。【-128~127】外的数字,包装类new新的对象来创造
异常
try-catch
finally语句一定会执行
没有return语句时,finally语句之后面的语句也会执行
public static void main(String[] args) {
try {
int a = 1 / 0;
}catch ( ArithmeticException w) {
System.out.println("error");
}
finally {
System.out.println("0k");
}
System.out.println("end");
}
}
包含return语句,执行的一定是finally内的语句(return 覆盖)
private static int f(){
try {
int a = 1 / 0;
return 1;
}catch ( ArithmeticException w) {
System.out.println("error");
return -1;
}
finally {
System.out.println("0k");
return 9;
}
// return 0;--报错,fianlly语句包含return语句,结束代码
}
结果:返回9
private static int f(){
try {
int a = 1 / 0;
return 1;
}catch ( ArithmeticException w) {
System.out.println("error");
}
finally {
System.out.println("0k");
}
System.out.println("oj");
return 0;
}