javaSE入门笔记

这篇博客详细介绍了JavaSE的基础知识,包括static关键字的使用,值传递与引用传递的区别,对象与类、栈和堆的概念,继承与重写机制,多态的应用,抽象类和内部类的特性,异常处理,以及String类的重要知识点和内存管理。
摘要由CSDN通过智能技术生成

javaSE笔记

1、static关键字

    //当方法用static关键字声明时,这个方法在他所在的类创建时,就创建了(方法被创建的早)
    //所以被static声明的方法不能调用没有声明static的方法
    public static void a(){
        b();  //此处会报错
    }
    //而未用static声明的方法是在类被实例化的时候创建的
    public void b(){
        a();  //这个可以有
public class Student {
    {
        //匿名代码块,在创建对象的时候执行一次
        System.out.println("匿名代码块");
    }
    static {
        //静态代码块,在类加载的时候就创建了,且永久的只执行一次
        System.out.println("静态代码块");
    }
    public Student(){
        System.out.println("构造方法");
    }
}
public class Test {
    public static void main(String[] args) {
        new Student();
        System.out.println("====");
        new Student();
    }
}
//结果(有序):静态代码块
//			 匿名代码块
//			 构造方法
//   		 ====
//	 		 匿名代码块
//     		 构造方法
//所以static代码块在类创建的时候就存在了,只在第一次new对象的时候执行一次;

静态导入包

import static java.lang.Math.*;
//可不写类名直接用方法
System.out.println(random()); 
//0.1242972520655512  随机数

被final修饰的类不能被继承

用static声明的属性是所有对象共享的,懂通过一个对象改变这个属性时,其他对象调用这个属性也会发生改变

2、java的值传递

public class demo02 {
    public static void main(String[] args) {
        int a=1;
        System.out.println(a);
        demo02.change(a);
        System.out.println(a);
    }
    public static void change(int b){
        b=10;
    }
}
//定义一个int类型的变量,当调用方法时,会把实参a的值传递形参b,在方法中改变了b的值,但是并没有改变a的值

3、引用传递

引用传递是传递了一个对象,但是他的本质还是值传递

//值传递不会改变值,而引用传递会改变值
public class demo03 {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);//null
        demo03.change(person);
        System.out.println(person.name);//大傻子
    }
    public static void change(Person person){
        person.name = "大傻子";
    }
}
class Person{
    String name;
}

4、对象与类、栈和堆

public class Pet {
    public String name;
    public int age;
    public Pet(){
    }
    public Pet(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public static void shout(){
        System.out.println(this.name+"叫了一下");
    }
}
//创建一个类,有name和age两个属性,一个shout方法

给这个类new两个对象,cat和dog

public class demo04 {
    public static void main(String[] args) {
        Pet cat = new Pet();
        cat.name = "菠菜";
        cat.age = 3;
        cat.shout();

        Pet dog = new Pet();
        dog.name = "波太郎";
        dog.age = 3;
        dog.shout();
    }
}

在对象创建之前(new之前),先在类中的方法区加载类和类中的静态方法,当实例化一个对象时,在栈中生成一个引用变量名(所以对象属于引用数据类型),栈—>堆,指向堆中非方法区中的某一模块!!!main方法在栈的最下面

在这里插入图片描述

5、继承

extends(扩展);子类继承父类,那么子类可以调用父类的方法和属性,但是private声明的不能被继承,当子类和父类具有相同的方法名或属性名时,使用子类的对象调用方法或属性时,优先使用子类的,可用this和super来区分;

且当实例化子类时,会首先检测他的父类有没有被实例化,如果父类没有被实例化,则先实例化父类(调用父类的构造器super() )

super注意点:

  1. 调用父类的构造方法,必须在构造方法的第一个

  2. 只能出现在子类中

  3. super和this不能同时调用构造方法

6、重写

需要有继承关系,则子类重写父类的方法

  1. 方法名必须相同
  2. 参数列表必须相同
  3. 修饰符:范围可以扩大单不能缩小,public>protected>default>private
  4. 抛出的异常:范围可以被缩小,但不能扩大

7、多态

public class Person {  //父类
    public void run(){
        System.out.println("Person-->run");
    }
    public void read(){
        System.out.println("Person-->read");
    }
}
public class Student extends Person {   //子类
    @Override
    public void run() {      //重写父类的方法
        System.out.println("Student-->run");
    }
    public void write(){     //子类独有的方法
        System.out.println("Student-->write");
    }
}
public class test {       //测试
    public static void main(String[] args) {
        //一个对象的实际类型是确定的
        //new Person();

        //可以指向的引用类型就不确定了:父类的引用指向子类

        //子类(Student) 能调用的方法都是自己或者父类的
        Student s1 = new Student();		//子类的对象new子类
        //父类型(Person)能指向子类,但不能调用子类独有的方法
        Person s2 = new Student();		//父类的对象new子类

        //对象能执行哪些方法,主要看左边,和右边关系不大,用时执行哪个方法看右边
        s1.run();      //Student-->run
        s2.run();	   //Student-->run
        s1.read();     //Person-->read
    }
}

多态注意事项

  1. 多态是方法的多态,属性没有多态
  2. 父类和子类,有联系 类型转换异常
  3. 存在关系:继承关系,方法需要重写,父类引用指向子类Father f1 = new Son();
  4. 不能被重写的方法:
    • static 方法,属于类,不属于实例
    • final 修饰的方法
    • private 方法:不能被继承

8、abstract–>抽象类

继承抽象类的所有类都必须要实现它的方法(子类时普通类)

接口可以多继承

  1. 抽象类不能new,只能靠子类去实现:约束
  2. 抽象方法必须在抽象类中,抽象类中可以有普通方法

9、内部类

9.1、普通内部类和静态内部类

一个类可以定义在另一个类的内部,叫做内部类

public class Outer {		//外部类
    private int id = 10;
    private void out(){
        System.out.println("这个方法在外部类里面");
    }
    public class Inner{		//内部类
        public void in(){
            out();
            System.out.println("这个方法在内部类里面");
        }
        public void getId(){
            System.out.println(id);
        }
    }
}
public class Tset {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        //要活得内部类的实例,就要先用外部类的对象去new内部类,得到的是一个Outer.Inner类型的对象
        inner.in();
    }
}
  1. 内部类的对象可以调用外部类的私有属性和方法
  2. 静态内部类,用static关键字修饰,这时就不能调用非静态的属性了

9.2、局部内部类和匿名内部类

**局部内部类:**写在方法里面的类

class demo {
    public void method(){
        class A{
            //暂时没有什么意义,就是花里胡哨
        }
    }
}

匿名内部类(略)

10、异常(Exception)

五个关键字:try、catch、finally、throw、throws

        int a=0;
        int b =1;
        System.out.println(b/a);
//会抛出异常:Exception in thread "main" java.lang.ArithmeticException: / by zero
//被除数不能为0

上述代码会造成异常,此时程序会报错停止,但是我们有的时候并不想让异常报错使程序停止,那么我们可以对有可能出异常的区域进行检测,如果发生异常,就抛出异常,此时程序依然可以向下执行;而finally则是无论程序出不出异常,finally里面的代码都会被执行,finally可以不要。

public class Test {
    public static void main(String[] args) {
        int a=0;
        int b =1;
        try{		//Ctrl Alt + t
            System.out.println(b/a);
        }catch (ArithmeticException e){
         //ArithmeticException是想要获得异常类型;最大是Throwable
            System.out.println("以上程序出现异常");
        }catch (Throwable e){  //catch可以有多个,但是大的必须在后面
            e.printStackTrace();
        }finally {
            System.out.println("finally");
        }
        System.out.println("结束");
    }
}
//结果(有序):
//		以上程序出现异常
//		finally
//		结束

主动抛出异常–throw、throws

public class Test01 {
    public static void main(String[] args) throws Exception{	//当在方法中处理不了一个异常,这时就要在方法上跑处置异常了
        int a = 0;
        int b = 6;
        if (a==0){
            throw new ArithmeticException();//主动抛出异常,在方法中
        }
    }
}
//结果:Exception in thread "main" java.lang.ArithmeticException(算数异常)

自定义异常:

//自定义的异常类
public class MyException extends Exception {
    private int detail ;			//一个int类型的属性
    public MyException(int detail) {
        this.detail = detail;
    }
    @Override
    public String toString() {		//打印异常信息
        return "MyException"+detail;
    }
}
public class ExceptionTest {
    //一个可能会出现异常的方法
    static void test(int a) throws MyException {
        System.out.println(a);
        if (a>10){
            throw new MyException(a);	//满足情况抛出异常
        }
        System.out.println("OK");
    }
    public static void main(String[] args) {
        try {
            test(11);
        } catch (MyException e) {
            System.out.println(e);
        }
    }
}//结果:
//11
//MyException11

11、补充:String

11.1、关于String类型和ASCII码及类型转换

众所周知当int型和字符串类型相加时,int类型可以自动转换为字符串类型,但是转化时是有顺序的

public class Test01 {
    public static void main(String[] args) {
        String str01 = "a"+ 1 + 2;
        int str02 	 = 'a' + 1 + 2;
        String str03 = 1 +2 + "a";
        System.out.println(str01);	//a12
        System.out.println(str02);	//100
        System.out.println(str03);	//3a
    }
}

11.2、关于String

  1. 一个字符串就是String类的匿名对象,匿名对象就是已经开辟了堆内存空间的并可以直接使用的对象

    public class Test {
        public static void main(String[] args) {
    		 System.out.println("hello".equals("helo"));
        }
    }
    //false
    

    输出结构为false,说明一个字符串确实可以调用String类中的方法,证明了一个字符串就是String类的匿名对象。

  2. 关于内存

    String str1 = "hello";
    

    此种形式声明了一个变量,实际上就是在堆中开辟好的堆内存空间的使用权给了str1这个对象;

在这里插入图片描述

这种方法还有一个好处就是,如果一个字符串已经被一个名称所引用,则以后再有相同的字符串声明时,不会再开辟新的空间,即:

public class Test {
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "hello";
        String str3 = "hello";
        System.out.println(str1==str2); //ture
    }
}

在这里插入图片描述

  1. 关于声明问题

    String str = new String("hello");
    

    此方法声明会开辟两块堆内存空间,其中有一块将会成为垃圾。

  2. 字符串的内容不可改变

    当改变一个字符串的内容时,其实并没有改变这个字符串在堆内存的内容,而是重新开辟一个空间,存入新的内容,在把栈中变量的引用指向新的内存空间。

    public class Test {
        public static void main(String[] args) {
            String str1 = "hello";
            System.out.println(str1.hashCode());  //99162322
            str1 = "fds";
            System.out.println(str1.hashCode());  //101237
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值