深入理解Java基础知识(一)

林黛玉
半卷湘帘半掩门,碾冰为土玉为盆。

偷来梨蕊三分白,借得梅花一缕魂。
2023-3-1第一次编辑


前言

本周开始跟着JAVAGuide学习Java基础,感谢Guide哥!欢迎大家一起讨论学习!


提示:以下是本篇文章正文内容,下面案例可供参考

一. JVM和JDK和JRE

JDK>JRE>JVM
JDK包含JRE,编译器javac和工具javadoc
JRE包含JVM,Java命令,Java类库
JVM包含,堆内存,栈内存等

二.从.class到源码

JVM会通过类加载器将.class文件变成机器码。
注意:字节码不分操作系统,也就是只有一种,但是JVM却是根据不同操作系统有不同的区别。因此也就有了“一次编译,随处运行”
但是对于那些经常调用的那些内容,这么做明显会减慢代码执行的速度。
因此后面引进JIT,属于运行时编译,也就是在一次从class文件变成机器码后,这一部分跟传统的JVM一样,但是会保留它对应的机器码,那么下次调用的时候,就会自动的识别出机器码,不需要解释器的帮助了。
因为先用javac编译成字节码,然后再解释成机器码。它跟编译型语言和解释型语言的语言特性都不同。这样也就解释了JAVA是编译和解释并存的语言了。

详细了解AOT和JIT:

https://blog.csdn.net/h1130189083/article/details/78302502

三.移位运算符

不支持float,double类型移位

        int i = 2; // 010
        int j = 4; // 100
        System.out.println(i << 2);// 向左移动两位
        System.out.println(i ^ j);// 110,异或
        System.out.println(Integer.toBinaryString(i ^ j));// 输出二进制
        System.out.println(i << 34); // 实际是34%32=2,结果也是8

四.变量

这是个经常被忽视的细节

一.成员变量和局部变量

要从根本上区分,局部变量属于方法内、参数、代码块中,并且不允许被static静态化,因为它不属于类,它只能存在于栈内存中。其次,它也不能被控制修饰符private,public等所影响。而且它没有默认值,必须由用户赋值,否则不通过
而成员变量则分成两种情况,由于它允许被static,那么当它被static的时候,那么它就是属于类的,那么它存储在方法区(一种说法是方法区也算堆中);反之,它则是属于实例的,被存储在堆内存中。并且它有默认值。

class AClass{
    public int a;
}
main(){
        AClass aClass = new AClass();
        System.out.println(aClass.a);// 编译不会报错
        String k;
//        System.out.println(k); // 编译会报错
}

详细了解static成员变量存储在哪里:

https://cloud.tencent.com/developer/ask/sof/54024

二.字符串常量

之所以单独列出来,是因为算法中常考到对应的ASCII值的转换
一个字符常量就是一个整型值,可以参与运算,占用两个字节

        char c = 'A';
        char c2 = 'a';
        System.out.println((c + 32) == c2);
        System.out.println(97 == c2);
        System.out.println((char)97); // 变成小a

五.方法

一.静态方法

从时间的角度来看,静态方法不允许访问非静态变量,那是因为无论是静态方法和静态变量都属于类,在JVM类加载的时候便存在了,比实例化更快,所以是访问不到的。

二.重载

重载是同一个方法的不同实现,Java规定方法名+参数来区分一个方法,因此想要重载,就得保证方法名不变,但是参数需要不同(包括顺序,个数)。构造方法也可以
注意:仅仅返回类型不同是不能算重载

    public int add(String b,int a){
        return 1;
    }
    // 会报错
    public String add(String b,int a){
        return "123";
    }
    // 改变顺序可以
    public int add(int a,String b){
        return 2;
    }

三.重写

发生在子类和父类之间,方法名和参数名需要相同。构造方法无法被重写,因为方法名不同。
如果修饰符是private/final,子类则不能重写。对于static也是,目前这点还不能理解为什么
这里还要注意,对于返回的类型,是可以稍微改变的,那么按照这种理解,能改变的一定是引用类型
这里放一张javaguide的图
在这里插入图片描述
其次,对于编译期和运行期这两点还不能理解到底是什么意思
详细了解:

https://www.cnblogs.com/eycuii/p/11461535.html

四.可变参数

    public void print1(String... s){
        for(String s1 : s){
            System.out.print(s1);
        }
    }

六.基本数据类型

什么是逃逸分析:

https://juejin.cn/post/6844903639308304397

对于逃逸的局部对象,JVM将它存储在栈上,而不是存储在堆上

包装类型的缓存机制

//  这样子的方式就适合,但是超过这个值[-127,128]就不会复用已有对象
//        Integer integer1 = 3;
//        Integer integer2 = 3;

//        这样子方式不适合,只能用equals才能成功比对
        Integer integer1 = new Integer(12);
        Integer integer2 = new Integer(12);

        if (integer1 == integer2)
            System.out.println("integer1 == integer2");
        else
            System.out.println("integer1 != integer2");

        Integer integer3 = 300;
        Integer integer4 = 300;

        if (integer3 == integer4)
            System.out.println("integer3 == integer4");
        else
            System.out.println("integer3 != integer4");

自动拆装箱

//        自动装箱和拆箱
        Integer i1 = 100;
        int i2 = i1;

可以通过字节码来具体过程
详细了解:

https://www.jianshu.com/p/f97d5880eaa5

介绍两个重要的类:

        System.out.println(1.01 + 2.02);// 得到的不是3.03
        BigDecimal bigDecimal = new BigDecimal("1.01");
        System.out.println(bigDecimal.add(new BigDecimal("2.02")));

        BigInteger bigInteger = new BigInteger(String.valueOf(Long.MAX_VALUE) + 2);
        System.out.println(bigInteger);
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值