java基础

一、java基础语法:

类:包含了属性和方法,描述了一类对象的行为和状态。类的写法:首字母大写。如果是多个单词的组合,那么每个字母的首字母都大写

对象:是类的实例。包含了类中定义的属性和方法。

实例变量:是对象的属性。每个对象都有独特的实例变量,对象的状态由这些属性决定。实例变量必须创建了对象之后才能由对象来引用这个实例变量。

面试问法:静态变量、实例变量、成员变量、局部变量的区别

静态变量用static修饰。只要程序加载了类的字节码,不需要创建实例对象,就会为静态变量分配空间。静态变量独立于方法之外,又称类变量,无论实例化多少个对象,静态变量都只有一个,也就是说所有的实例对象修改的都是同一个静态变量,存储在静态存储区。可以直接用类名调用,也可以用对象名调用。

  • 类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致。

实例变量:独立于方法之外,不用static修饰,声明在一个类中,但在方法、构造语句和语句块之外。数值型变量默认值为0,布尔型变量默认值为false,引用类型默认值为null

成员变量:成员变量包括实例变量和静态变量,定义在方法体和语句块之外,一般定义在类的声明下。成员变量可以被类中方法、构造方法和特定类中的语句块访问。存储在堆内存的对象中

局部变量:定义在方法内部、构造方法或语句块中,不用访问控制符修饰,在栈上分配,没有默认值必须初始化。变量声明和初始化都在方法中,方法结束后变量会自动销毁

成员变量和类变量的区别:

成员变量和类变量的区别

成员变量和类变量的区别:

   1、两个变量的生命周期不同

      成员变量随着对象的创建而存在,随着对象的回收而释放。静态变量随着类的加载而存在,随着类的消失而消失。

   2、调用方式不同

      成员变量只能被对象调用。 静态变量可以被对象调用,还可以被类名调用。

   3、别名不同

      成员变量也称为实例变量。静态变量也称为类变量。

   4、数据存储位置不同

      成员变量存储在堆内存的对象中,所以也叫对象的特有数据。静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。

static 关键字,是一个修饰符,用于修饰成员(成员变量和成员函数)。

   特点:

   1、想要实现对象中的共性数据的对象共享。可以将这个数据进行静态修饰。

   2、被静态修饰的成员,可以直接被类名所调用。也就是说,静态的成员多了一种调用方式。类名.静态方式。

    3、静态随着类的加载而加载。而且优先于对象存在。

弊端:

   1、有些数据是对象特有的数据,是不可以被静态修饰的。因为那样的话,特有数据会变成对象的共享数据。这样对事物的描述就出了问题。所以,在定义静态时,必须要明确,这个数据是否是被对象所共享的。

   2、静态方法只能访问静态成员,不可以访问非静态成员。

      因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。

   3、静态方法中不能使用this,super关键字。

      因为this代表对象,而静态在时,有可能没有对象,所以this无法使用。

 

什么时候定义静态成员呢?或者说:定义成员时,到底需不需要被静态修饰呢?

成员分两种:

   1、成员变量。(数据共享时静态化)

      该成员变量的数据是否是所有对象都一样:

      如果是,那么该变量需要被静态修饰,因为是共享的数据。 

      如果不是,那么就说这是对象的特有数据,要存储到对象中。 

   2、成员函数。(方法中没有调用特有数据时就定义成静态)

      如果判断成员函数是否需要被静态修饰呢?

      只要参考,该函数内是否访问了对象中的特有数据:

      如果有访问特有数据,那方法不能被静态修饰。

      如果没有访问过特有数据,那么这个方法需要被静态修饰。

 

成员变量和静态变量的区别:

   1、成员变量所属于对象。所以也称为实例变量。

      静态变量所属于类。所以也称为类变量。

   2、成员变量存在于堆内存中。

      静态变量存在于方法区中。

   3、成员变量随着对象创建而存在。随着对象被回收而消失。

      静态变量随着类的加载而存在。随着类的消失而消失。

   4、成员变量只能被对象所调用 。

      静态变量可以被对象调用,也可以被类名调用。

   所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。

 

方法:方法就是行为,一个类可以有多个方法。方法的写法:所有的方法都应该是小写字母开头。如果是多个单词的组合,那么第一个单词的首字母小写,其余单词的首字母均为大写

package com.cuiinsist.myfirst.mapper;

public class BianLiang {
    private int id;   //private修饰的变量必须通过get\set方法设置或获取
    private String name;
    private String sex;
    public int nua;

    public static final String school="xian university"; //final修饰的成员变量必须被初始化,在主程序里用final修饰的变量不需要
    public static int num;

    public int getId(){
        return id;
    }

    public String getName(){
        return name;
    }

    public String getSex(){
        return sex;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name){
        this.name=name;
    }

    public void setSex(String sex){
        this.sex=sex;
    }

    public void infoStu(){
        String str1="我是";
        String str2="瑞";
        System.out.println("学生信息"+str1+str2);
        num++;
        System.out.printf("num:"+num);
        System.out.printf("布尔默认值"+nua);
    }

    public static void main(String[] args) {
        BianLiang bianhua=new BianLiang();
        bianhua.setId(1);
        bianhua.setName("lili");
        bianhua.setSex("man");
        bianhua.infoStu();
        System.out.printf("学校:"+BianLiang.school+"学生信息"+bianhua.getId()+"姓名"+bianhua.getName()+"性别:"+bianhua.getSex());
        BianLiang bianbian=new BianLiang();
        bianbian.infoStu();

    }
}

运行结果:

学生信息我是瑞
num:1布尔默认值0学校:xian university学生信息1姓名lili性别:man学生信息我是瑞
num:2布尔默认值0 

num是static修饰,可以看出两个BianLiang对象修改的是同一个num

二、 java标识符

类名、变量名、方法名都被称为标识符。

java标识符命名规则:①所有的标识符都必须以字母(A-Z,a-z)美元符($)、下划线(_)开头,数字不能作为标识符的开头。②:首字母之后,可以是字母、数字、下划线、美元符

③:关键字不能用作标识符      ④:标识符是区分大小写的

三、java修饰符

访问控制符(用来保护对类、变量、方法、构造方法的访问)

default(默认不写):在同一个包中的可以访问,可以用来修饰类、变量、方法、接口

private:仅在同一个类中可用。可以用来修饰变量、方法,不能修饰类和接口(因为接口就是用来被访问修改的,类也是用来被访问的)

protected:对同一个包内的类和子类可用。可用来修饰变量和方法。不能用来修饰类和接口

接口里的变量都隐式声明为public static final,接口里的方法默认情况下都声明为public

private

数据域封装:为了避免对数据域的直接修改,就是将变量声明为private,私有化,使类易于维护。在定义私有域的类外的对象是不能访问这个数据域的。但是为了能够更新私有数据域,可以提供一个set方法给数据域提供新值,为了能够访问私有数据域,可以提供一个get方法返回数据域的值。被声明为 private 的方法、变量和构造方法只能被所属类访问,并且外部类和接口不能声明为 private

公有访问修饰符-public

被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。

如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public 类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。

Java 程序的 main() 方法必须设置成公有的,否则,Java 解释器将不能运行该类。

受保护的访问修饰符-protected

protected 需要从以下两个点来分析说明:

  • 子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;

  • 子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法

protected 可以修饰数据成员,构造方法,方法成员,不能修饰类(内部类除外)

接口及接口的成员变量和成员方法不能声明为 protected。

子类能访问 protected 修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。如果我们只想让该方法对其所在类的子类可见,则将该方法声明为 protected。

访问控制和继承

请注意以下方法继承的规则:

  • 父类中声明为 public 的方法在子类中也必须为 public。

  • 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。

  • 父类中声明为 private 的方法,不能够被继承

 

非访问控制符

static 修饰符,用来修饰类方法和类变量。

final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。

abstract 修饰符,用来创建抽象类和抽象方法。

synchronized 和 volatile 修饰符,主要用于线程的编程。

static 修饰符

  • 静态变量:

    static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。多个对象共有一个静态变量,也就是说多个对象修改的是同一个静态变量

  • 静态方法:

    static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。如果想使用非静态变量,必须得实例化,实例化之后用对象引用非静态变量。实例方法可以调用实例的方法、数据域,也可以调用静态的方法和数据域

final 修饰符

final 变量:

final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。

final 修饰符通常和 static 修饰符一起使用来创建类常量。

final 方法

父类中的 final 方法可以被子类继承,但是不能被子类重写。

声明 final 方法的主要目的是防止该方法的内容被修改。

abstract 修饰符

抽象类:

抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。

一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误

抽象类可以包含抽象方法和非抽象方法

抽象方法

抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。

抽象方法不能被声明成 final 和 static

任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。

如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法

抽象方法的声明以分号结尾,例如:public abstract sample();

synchronized 修饰符

synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。

transient 修饰符

序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。

该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。

volatile 修饰符

volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

一个 volatile 对象引用可能是 null。

 

四、java接口

在 Java 中,接口可理解为对象间相互通信的协议。接口在继承中扮演着很重要的角色。

接口只定义派生要用到的方法,但是方法的具体实现完全取决于派生类。

五、Java 源程序与编译型运行区别

如下图所示:

六、java的构造方法:

每个类都有构造方法,如果没有显示地为类添加构造方法,会默认定义一个方法体为空的无参构造方法。这个构造方法称为默认构造方法。当且仅当类中没有明确定义任何构造方法时才会自动提供。

构造方法三个特殊性:

1、构造方法必须具备和所在类相同的名字

2、构造方法没有返回值类型,甚至连void也没有

3、构造方法是在创建一个对象使用new操作符时调用的,不能由程序编写者直接调用,必须由系统调用。构造函数在对象实例化时会被自动调用,且只运行一次,而普通的方法可被调用多次。构造方法的作用是初始化对象。

4、构造方法可以重载(也就是可以有多个同名的构造方法,但他们要有不同的签名方法,也就是参数个数),更易于用不同的初始数据值来构造对象。

5、每个类可以有多个构造函数。每个构造函数可以有0个、1个或1个以上的参数。

6、构造函数不能被继承,因此他不能被覆盖。

package com.cuiinsist.myfirst.mapper;

public class BianLiang {
    private String name;
    private String sex;

    //构造方法
    public BianLiang(String newname){
        name=newname;
    }
    public BianLiang(String newname,String newsex){
        name=newname;
        sex=newsex;
    }

    public void infoStu(){
        System.out.printf("name:"+name);
    }

    public static void main(String[] args) {
        BianLiang bianhua=new BianLiang("lily");
        BianLiang bianjia=new BianLiang("jack","female");
        bianhua.infoStu();
        bianjia.infoStu();
    }
}

7、子类可以通过super关键字显示调用父类的构造函数,当父类没有提供无参数的构造函数时,子类的构造函数中必须显示地调用父类的构造函数。如果父类提供了无参数的构造函数,此时子类的构造函数就可以不显示地调用父类的构造函数,这种情况下系统会默认调用父类提供的无参构造函数。有父类时,在实例化对象时会先执行父类的构造函数,然后执行子类的构造函数。

package com.cuiinsist.myfirst.mapper;

class Father{
    Father(){
        System.out.println("Father");
    }
    Father(int i){
        int j=i;
        System.out.println(j);
    }
}

public class Son extends Father{//有父类时,实例化对象会先执行父类构造函数
    Son(){
        //super(1);//在子类的构造函数中显示调用父类的有参构造函数
        System.out.println("Son");
    }

    public static void main(String[] args) {
        Son s1=new Son();
    }
}

 输出结果:

Father
Son                             

七、java定义类和创建对象

可以把两个类放在同一个文件中,但是文件中只能有一个类是公共类(public)。此外,公共类必须和文件同名。源代码中的每个类都会被编译成.class文件。如下代码中,BianLiang.java编译时,会产生两个类文件:BianLiang.class,Moon.class

package com.cuiinsist.myfirst.mapper;

public class BianLiang {
    //静态main方法不能引用非静态。所以Moon必须得是静态
    static class Moon {
        Moon(String newname){
            name=newname;
        }
        Moon(String newname,String newsex){
            name=newname;
            sex=newsex;
        }
        //内部类的成员变量不能是static
        private String name;
        private String sex;
        public void infoStu(){
            System.out.printf("name:"+name);
        }
    }
    public static void main(String[] args) {
        Moon bianhua=new Moon("lily");
        Moon bianjia=new Moon("JACK","man");
        bianhua.infoStu();
        bianjia.infoStu();
    }
}

内部类

非静态内部类(需要先实例化外部类,通过外部类的实例来创建内部类的对象)

package com.cuiinsist.myfirst.mapper;

class Outter{
    int x=10;
    class Inner{
        int y=x; //可以调用外部类的成员
    }
}
public class Try {
    public static void main(String[] args) {
        Outter out=new Outter();
        Outter.Inner nei=out.new Inner();
        System.out.println(out.x+ nei.y);
    }
}

输出结果:20 

静态内部类(不需要实例化外部类的对象,可以直接new内部类的对象。但是静态内部类不能直接调用外部类的成员)

package com.cuiinsist.myfirst.mapper;

class Outter{
    int x=10;
    static class Inner{
        int y=x;
    }
}
public class Try {
    public static void main(String[] args) {
        Outter.Inner nei=new Outter.Inner();
        System.out.println(nei.y);
    }
}

输出结果:会报错。因为静态内部类不能直接调用外部类成员。除非把外部类成员变成静态的 


匿名类:https://www.runoob.com/java/java-anonymous-class.html 


 

创建对象

使用new来创建一个对象。创建对象需要以下三步:

1、声明:声明一个对象,包括对象名称和对象类型

2、实例化:使用关键字new来创建一个对象

3、初始化:使用 new 创建对象时,会调用构造方法初始化对象

Moon bianhua=new Moon("lily");

new关键字的作用

1、为对象分配内存空间。

2、引起对象构造方法的调用。

3、为对象返回一个引用。

函数传参

传递对象

传递对象传递的是对象的地址或者引用,修改对象里面的值,实际上是在地址空间里修改这个对象的参数,则参数的值一定会被修改

package com.cuiinsist.myfirst.mapper;

class Bob{
    int a=1;
    int c=2;
}

public class Try {
    public static void main(String[] args) {
        Bob bob=new Bob();
        func(bob);
        System.out.printf("结果:"+"a:"+bob.a+"    c:"+bob.c);
    }

    public static void  func(Bob a){
         a.a++;
         a.c++;

    }
}

运行结果:

结果:a:2    c:3

传递参数

传递参数时在另一个函数里修改这个参数,通过return方法只是将结果返回,但是对象里面实际的参数的值没有被改变

package com.cuiinsist.myfirst.mapper;

class Bob{
    Bob(){
        System.out.println("构造");
    }
    int a=1;
    int c=2;
}

public class Try {
    public static void main(String[] args) {
        Bob bob=new Bob();
        int num=func(bob.a);
        System.out.println("return回来的值:"+num+"  对象实际的参数:"+bob.a);
    }

    public static int  func(int a){
        int b=a++;
        return a;
    }
}

 运行结果:

构造
return回来的值:2  对象实际的参数:1

 

问1:为什么需要public static void main(String[] args)这个方法

答:它是java程序的入口方法,JVM在运行程序时,会首先查找main方法。JVM在启动时按照(必须有static  public 修饰,返回值为void,且方法的参数为字符串数组)来查找方法的入口地址,若能找到就执行否则报错,该方法不需要实例化对象,存储在静态存储区,main是JVM识别的特殊方法名,是程序的入口方法。

问2:main()方法是否有其他可用的定义格式

1、static public void main(String[] args)

2、public static final void main(String[] args)

3、public static synchronized void main(String[] args)

不能用abstract关键字修饰

问3:同一个.java文件中是否可以有多个main()方法

可以。但是只有与文件名相同的用public修饰的类中的main方法才能作为整个程序的入口方法

问4:如何实现在main()方法执行前输出“Hello”(程序运行时最先加载main()方法,那么main()方法是程序运行时第一个被执行的模块吗)

可以在类里面写一个静态块。在java中,静态块在类被加载时就会被调用,因此可以在main()方法执行前,利用静态块实现输出“hello”的功能。如下所示。

public class Charac {
    static{
        System.out.println("我先出");
    }
    public static void main(String[] args) {
        System.out.println("我后出");
    }
}

问5:java程序初始化的顺序是怎样的?

java中实例化对象时,对象所在类的所有成员变量首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在类的构造函数创建对象

初始化原则(优先级依次递减)

①:静态对象(变量)优先于非静态对象(变量)初始化,其中,静态对象(变量)只初始化一次,而非静态对象(变量)可能会初始化多次

②:父类优先于子类进行初始化

③:按照成员变量的定义顺序进行初始化

不同代码块中的执行顺序:

父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页