Java基础

Java基础,第1张

Java基础 基本语法 字符型常量和字符串常量的区别? 1. 形式:

字符常量是由单引号括起来的一个字符,而字符串是由双引号括起来的0个或者多个字符

最简单的例子:

char a1='0';
char a2='*';
char a3='a';

String s1="";
String s2="*asd";
String s3= "0";
2. 含义

字符串常量表示的是地址值,表示的该字符串在内存地址中存放的位置,而字符常量可以理解为ASCII表,可以进行相应的运算

3. 占用的内存大小

字符一次占用2个字节,字符串占用若干个字节

标识符与关键字 1. 区别:

​ 在平时编码过程中我们需要对变量、类、对象起名字,我们所起的名字其实就是一个标识符,他标识这某个特定的对象,我们所起的标识符有特别多但是有几个经常使用,这时候就将这些经常使用的标识符赋予特殊的含义,使其只能使用在特定的位置上,这就是关键字,最简单例子就是:

2.常见的类型 1. 权限控制:

private public protected

2. 类,方法和变量修饰符

abstract class extends implements interfaces native final new static。。。。。。

3. 程序控制

break return contiunue do while if else for instanceof switch case default

4. 异常处理

try catch throw finally

5. 包相关

import package

6. 基本数据类型

boolean int short long float double byte char

7. 引用类型

super this

自减 自增运算符

自减运算符: –

自增运算符 ++

表示:如果放在前面,则表示先自我 *** 作(+1或者-1)在进行 *** 作,如果放在后面则表示先进行赋值或者其他 *** 作,在进行自我的 *** 作(-1或者-1)

基本数据类型 三大类 1. 数字类型 int long short byte float double 2. 字符类型 char 3.布尔类型 boolean 类型位数字节默认值int40short20long80Ldouble80dfloat40fbyte10char2‘u0000’booleanfalse 包装类型:

Integer、 Boolean 、Long、 Short 、Double、 Float 、Byte 、Character

包装类型不赋值默认为null 而不是0,而 基本类型不赋值默认不为null

装箱与拆箱 装箱:将基本类型用它们对应的引用类型包装起来; 拆箱: 将包装类型转为基本类型 装箱代码:

在装箱过程中,我们进入查看其源代码,发现调用的valueOf()方法,这里我们以Integer方法为例

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
拆箱实际代码

再拆箱过程中实际调用的代码为:

public int intValue() {
    return value;
}

这是将Integer转换为int类型的过程中调用的方法,如果是转为long则调用 longValue()方法等等、、、、

其他的拆箱过程大致是相同的

数据类型的封装类,以及中间的区别 封装类

Integer、 Long 、Short、 Double 、Float、 Boolean 、Character

通过源码分析我们可以得知,除了Double、Float、Boolean 中不存在缓存,而其余的都存在缓存,这个缓存能够加快其速度,使其更加快速的进行 *** 作,此外Character与其他的缓存不相同,其余的缓存时-128~127,但是Character的缓存时<128

补充
Integer num1 = 100;
Integer num2 = 100;
System.out.println(num1 == num2);
Integer num3 = 128;
Integer num4 = 128;
System.out.println(num3 == num4);
Integer num5 = new Integer(100);
Integer num6 = new Integer(100);
System.out.println(num5 == num6);
int c = 100;
System.out.println(num5 == c);
System.out.println(num6 == c);

分析:

大前提: == 比较的时内存地址,如果是int。。的数字比较的时值,也可以理解为比较的就是值,而封装类型、引用类型的值为地址值

num1 == num2 =>true

由于100在缓存的范围内,直接存在在内存中,在赋值的时候将其值赋予给他,此时的直接赋值本质上就是从内存池中去获取地址,获取的地址值是相同的,所以未相同的

num3 == num4 = > false

在此刻已经超出了缓存范围,这时候执行的是另一个方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YYpXiACa-1638014022668)(%E6%B1%87%E6%8A%A5.assets/image-20211122202045602.png)]

可以看到此时走的是new方法,new方法一走地址值必不相同,故返回false

num5 == num6 => false

由于返回的是两个new 故必不相同

c == num5 =>true

c == num6 =>true

这是由于在比较的时候封装类型会卸去封装,转换为相应的类型,那么则会进行数值上的比较,故为true

方法 方法的几种类型

无返回值需要void关键字

1. 无参无返回值
public void test01(){
    System.out.println("test01");
}
2. 有参无返回值
public void test02(int a ,int b){
    System.out.println("a"+"+"+"b"+"="+(a+b));
}
3. 无参有返回值
public String test03(){
    return "hello world";
}
4. 有参有返回值
public String test04(String result){
    return result;
}
5. 无返回值 使用return
public void test05(int a){
    if (a<5){
        return;
    }
    a++;
    System.out.println(a);
}

在这里的return 起到的作用是终止方法

返回值 什么是返回值

返回值顾名思义:返回回来的值,在我们的方法产生一个结果进行返回, *** 作后供其他的变量或者其他方法使用。

返回值的类型 1. 八种基本数据类型 2. 基本类型的封装类型 3. 类

在这里可以举个例子

public User user(){
    User user = new User();
    return user;
}
静态方法的特殊性 1. 在使用的时候不需要进行new

在进行反射的时候我们发现static总是先被编译,然后再是其他的方法,也就是说我们在使用方法的时候可以直接调用,不用在重新new

2. 可以直接通过类进行访问

举例:

public User user(){
        Other.test03();
        User user = new User();
        return user;
    }

这里的test03如下:

public class Other {
    public static void test03(){
        System.out.println("11111");
    }
}

可以发现能够直接调用

3. 可以被非静态调用,但不能被静态调用
 public static void kda1(){
        test05();
    }

只是后IDEA直接提示错误:

4. 不能够使用this关键字,我们知道static是最先编译的,如果使用this可能会造成内存出现错误

这个需要结合 JVM 的相关知识,静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,然后通过类的实例对象去访问。在类的非静态成员不存在的时候静态成员就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法 *** 作。

5. 更为特殊的: main方法

main方法是静态的

实例方法以及和静态方法的区别 1. 调用方法不同

静态方法调用不需要实例化,可以直接使用对象名.方法进行调用,而实例对象需要进行实例化才能够调用

2. 限制不同

在静态方法中不能调用实例化对象,但是在实例化对象中不存在这种限制

解释

静态方法是属于类的,在类加载的时候就会存在内存分配,可以直接通过类名直接进行访问,实例对象只有在实例化后才存在,然后通过类的实例化对象去访问,也就是说实例化对象不存在的时候静态方法已经存在在了,在此时调用内存中不存在的非静态方法属于非法 *** 作。

值传递与引用传递 什么是值传递?

说简单单点值传递就是将值进行传递,而不是其地址值,可以看成一个成员变量,在 *** 作后不影响其全局 *** 作。

是使引用传递?

引用传递,可以理解为通过引用的方式进行传递,那么引用的是什么呢?引用的是地址值,将地址值进行传递,供其进行 *** 作, *** 作后会影响全局

值传递示例:
public class method2 {
    public static void main(String[] args) {
        methodss();
    }
    private  static void methodss(){
        int a =4;
        methods(a);
        System.out.println("methodss 中a="+a);
    }
    private static void methods(int a){
        a+=2;
        System.out.println("a="+a);
    }
}

我们查看其结果:

显然最后a的值没有改变,也就是说在传参为基本数据类型的过程中,进行的是值传递,不会影响其地址值

引用传递示例:
public class method2 {
    public static void main(String[] args) {
        int[] a ={1,2,3,4,5,6};
        methods3(a);
        System.out.println(a[2]);
    }
   
    private static void methods3 (int[] a){
        a[2]=10000;
    }
}

输出结果为:

由此可知,在进行参数传递的过程中,如果参数的类型为基本数据类型,那么进行的是值传递,也就是说在原方法中进行 *** 作不影响原方法参数的值,若不是基本数据类型,则进行的是引用传递,传递的是地址值,在方法中进行修改等价于修改该地址之中的数据

重载和重写 什么是重载?

发生在同一个类中(或者父类和子类之间),方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同。

示例:

public class method3 {
    public void methods1(){

    }
    public void methods1(int a ){
        System.out.println(a);
    }
    public String methods1(String a,String b){
        return a;
    }
    public Integer methods1(String a,Integer b){
        return b;
    }
    public Integer methods1(Integer a ,String b){
        return a;
    }

}
什么是重写?

重写,可以理解为重新编写,发生在运行阶段,是子类对父类的允许访问的方法进行重新编写。

重写的要求:
  1. 返回值类型、方法名、参数列表必须相同,抛出的异常必须小于等于父类抛出的异常,访问修饰符范围要大于等于父类
  2. 如果父类的方法被 private final static 修饰,那么不能进行重写
  3. 构造方法无法被重写

重写就是子类对父类方法的重新改造,外部样子不能改变,内部逻辑可以改变。

重载与重写的区别 深拷贝与浅拷贝 1. 什么深拷贝?

深拷贝的作用是将一个对象的所有信息进行一个copy,在copy的同时在开辟一个新的内存进行存放,使得原来的变量与现在的变量进行了一个隔离,互相修改不会影响。

2. 什么是浅拷贝

浅拷贝就是直接copy对象的地址值,在copy之后不存在隔离,一个修改,则另一个也会受到影响。

3. 如何进行拷贝? 1. 深拷贝的方式:
  1. 通过实例化

    手动赋值,效率100%,但是代码重复

  2. 通过clone

    重写Object下的clone的方法,借此进行深拷贝

    重写方法:

    此外实体类对象还要实现一个接口Cloneable 点击查看这个接口我们发现其无任何内容仅仅就是一个空接口

  1. 通过json

    在使用json进行拷贝的时候实际上是利用了反射的方法进行的拷贝

2. 浅拷贝

浅拷贝的方式比较简单,可以直接将值赋给他就OK了

示例:

面向对象 面向对象和面向过程 什么是面向对象?

面向对象是一种思想,他不考虑那么多,把一切事物对象化,主要体现为 封装、继承 多态

什么是面向过程?

面向过程也是一种思想,他与面向对象相比更加关注于过程,通过分析问题去寻找步骤编写代码最后在一个一个进行调用

面向过程与面向对象的区别: 面向对象:

更容易维护、易复用、易拓展,由于封装继承的存在,使得耦合更加的低、系统更加灵活,更容易维护,但是由于是面向过程,在调用的时候需要进行实例化,会消耗大量的内存与资源,使得性能较差

面向过程:

面向过程的性能比面向对象高的多,但是维护起来比较麻烦

成员变量、局部变量 成员变量与局部变量的理解

可以简单地理解为 成员变量是属于类的变量,而局部变量是属于方法中的变量

示例:

成员变量与局部变量的区别:
  1. 从语法形式上看成员变量是属于类的,而局部变量是在方法中定义或者参数中的变量。此外,成员变量可以被static public private 等修饰符进行修饰,而局部变量不能被访问修饰符以及static进行修饰
  2. 从变量在内存中的位置来看: 如果成员变量被static进行修饰,那么这个成员变量是属于类的,反之则是属于实体类、实例的,而对象存在于堆内存中,局部变量是存在于栈内存中。
  3. 从存在时间上看,局部变量的寿命要比成员变量长,成员变量是类的一部分,它随着类的创建而创建,而局部变量则是随着方法的调用而创建,方法执行结束后消亡。
  4. 从是否有默认值来看: 成员变量如果没有赋值,则会有一个默认值,而局部变量不会,(final方法除外)
对象实体和对象引用的区别 构造方法的特点与作用: 作用:

主要是为了完成类对象的初始化工作

构造方法的特点:
  1. 名字必须与类名相同
  2. 没有返回值,但是不能用void声明关键字
  3. 生成类时自动调用,无需手动调用

构造方法不能被重写(override) 但是能够被重载(overload),类中可以存在多个构造对象

如果一个类没有声明构造方法,那么该程序还能正常进行。

如果一个类没有声明构造方法,在编译过程中会自动补齐,会生成一个默认的无参构造方法,程序继续进行编译,如果已经声明了构造方法,那么不会在补齐构造方法,会使用当前已经声明的

面向对象的三大特征: 1. 封装

封装: 简单的理解就是把它给装起来打包好,指的是把一个对象的属性信息隐藏在对象内部,不允许外部程序直接进行访问,但是完全封装的对象无法进行 *** 作也没有了实际作用,所以本身还是提供一些方法供外界机型 *** 作、获取信息 再次过程中主要使用的关键字为 private

示例

class teacher implements Cloneable{
    private String name;
    private String sex;
    private Integer age;

    public teacher(String name, String sex, Integer age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public teacher() {
    }
    //供外界获取name信息
    public String getName() {
        return name;
    }
    
    //供外界设置name信息
    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return (teacher)super.clone();
    }
}
2. 继承 什么是继承?

继承是Java面向对象的基石,它允许创建分等级层次的类

继承就是子类继承父类的特征和行为,使得子类对象具有父类的方法与属性,或者子类从父类继承方法,是子类与父类有相同的行为

继承的特性
  1. 子类可以继承父类的非private 的属性与方法

  2. 子类可以有用自己的属性与方法,及子类可以对付类进行拓展

  3. 子类可以实现或者重写父类的方法

  4. Java的继承是单继承,但是可以多重继承。

    单继承就是一个类只能有一个父类,多重继承其实是某个子类可能是某个类的子类的子类

  5. 提高了耦合度(这是继承的一个缺点,提高了耦合度,使得代码之间的独立性越来越差);

实现继承的关键字: extends

格式:

class A extends B{
    ......
}
继承中的关键字: super 与this super关键字 : 通过super关键字可以实现对父类的成员变量或者成员方法进行访问、调用 this关键字: this关键字指向自身,表示对自身的成员变量或者方法进行调用 final

如果final修饰一个类,表示这个类是最终类,无法被继承

如果修饰一个方法,则表示这个方法无法被重写

其他

我们需要知道的是在调用子类的构造方法的时候会默认调用父类的构造方法:

示例:

子类:

父类:

折叠起来的是get、set方法

我们调用子类:

输出结果如下:

3. 多态 多态的理解

多态,字面意思就是多种状态,表示一个对象具有多种状态,距离表现为一个父类可以指向多个子类的实例

举个葫芦娃的例子,葫芦小金刚是7个葫芦娃的融合体,拥有每个葫芦娃的技能,我们将他视为每个葫芦娃的父类,他的子类(葫芦娃们)的状态、技能各不相同,这就是他的多态。

特点:
  1. 对象类型和引用类型之间具有继承或者实现关系
  2. 引用类型变量发出的方法的调用到底是哪个类中的方法,必须在程序运行期间才能够确定
  3. 多态不能够调用只在子类中存在而父类中不存在的方法
  4. 如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果没有进行重写,则默认调用父类的方法
I/O流 序列化与反序列化 什么是序列化?

序列化是将数据转换成二进制字节流的过程

什么是反序列化?

通过序列化将数据转换成二进制字节流的形式,反序列化就是想二进制字节流的数据转换成数据结构或者对象。

序列化的作用

序列化的目的是通过网络传输对象或者说是将对象存储在文件系统、数据库、内存中

键盘输入的实现方式 键盘输入的方式有两种,一种是通过Scanner的方式获取:
		Scanner scanner=new Scanner(System.in);
        String s =scanner.next();
        scanner.close();
通过流的方式BufferedReader :
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
try {
    s= reader.readLine();
} catch (IOException e) {
    e.printStackTrace();
}
避免序列化的方法: transient

transient能够避免进行序列化

作用: 阻止实例中那些用词关键字修饰的变量进行序列化,当对象进行序列化的时候,transient修饰的变量值不会被持久化和回复。 注意:
  1. transient只能修饰变量,不能修饰类与方法
  2. transient 修饰的变量,在序列化后变量值会被默认替换为类型的默认值,如果为int类型,则反序列化后的结果为0
  3. static变量因为不属于任何对象,所以无论有没有transient都不会被序列化
字节流与字符流 1. 什么是字节流?

字节流,是以Java中的自己为最基本的单位进行处理,通常用来处理二进制数据,例如图片、视频、音乐

2. 字符流

Java中的字符流处理的最基本的单元式Unicode(大小为2字节),通常用来处理文本文件

字符流与字节流的区别
  1. 字节流 *** 作的最基本单元是字节,而字符流 *** 作的最基本单元式Unicode,字符占两个单位
  2. 字节流默认不使用缓冲区,而字符流使用缓冲
  3. 字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
try {
    s= reader.readLine();
} catch (IOException e) {
    e.printStackTrace();
}
避免序列化的方法: transient

transient能够避免进行序列化

作用: 阻止实例中那些用词关键字修饰的变量进行序列化,当对象进行序列化的时候,transient修饰的变量值不会被持久化和回复。 注意:
  1. transient只能修饰变量,不能修饰类与方法
  2. transient 修饰的变量,在序列化后变量值会被默认替换为类型的默认值,如果为int类型,则反序列化后的结果为0
  3. static变量因为不属于任何对象,所以无论有没有transient都不会被序列化
字节流与字符流 1. 什么是字节流?

字节流,是以Java中的自己为最基本的单位进行处理,通常用来处理二进制数据,例如图片、视频、音乐

2. 字符流

Java中的字符流处理的最基本的单元式Unicode(大小为2字节),通常用来处理文本文件

字符流与字节流的区别
  1. 字节流 *** 作的最基本单元是字节,而字符流 *** 作的最基本单元式Unicode,字符占两个单位
  2. 字节流默认不使用缓冲区,而字符流使用缓冲
  3. 字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5611797.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存