刷题01(牛客)

目录

==和equals,hashcode常见错误

序列化

线程抢占资源

abstract和final

Java类加载器

引导类加载器(bootstrap class loader):

扩展类加载器(extensions class loader):

系统类加载器(system class loader):

反射


==和equals,hashcode常见错误

 equal:

不能用于基本数据类型的比较(因为这是一个继承与Object的方法);

用于进行对象的比较,二者的引用地址是否相同;

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

==:

用于基本数据类型比较,比较二者值是否相等;

引用数据类型也可以比较,比较二者地址是否相等;

不能用于基本数据类型和引用数据类型比较(拆箱另说)

特殊情况:

1.涉及自动装箱和自动拆箱的情况;

2.引用数据类型和基本数据类型比较时(equals)涉及自动装箱和自动拆箱;

注意:如果多个字符串变量值相同,则它们指向同一个地址;(字符串创建时,会在串池中进行寻找,找到时就不进行创建了);

itern()方法不要忘记了;

hashcode:

他和equals有约定关系:

1.如果两个对象相等——>equals()返回true,那么它们一定具有相同的哈希值hashcode;

2.如果两个对象的hash值相等,那么它们的对象可能不相等;

例子

1.假设有以下代码String s = "hello";String t = "hello";char c [ ] = {'h','e','l','l','o'};

t.equals (c);返回false——>根据上面equals源码可以知道一个时String,一个字符;

2.

 第一个:基本数据类型与引用数据类型进行比较(==),引用数据类型进行拆箱,然后比较的值就是里面的参数值,所以为true;

第二个:引用数据调用equals与基本数据类型进行比较时,基本数据类型会进行自动装箱,因为Integer类重写了equals方法,所以说只要两个对象的值相同,就可以视为同一对象;

所以为true;


序列化

介绍: 1.以某种存储形式使自定义对象持久化;2.将对象从一个地方传到另一个地方;3.使得程序更具有维护性;

 记住一句话:序列化的是对象,不是类,通过类调用的不会序列化;

 Java在序列化时不会实例化static变量和transient修饰的变量,因为static代表类的成员,transient   代表对象的临时数据,被声明这两种类型的数据成员不能被序列化;

所以值分别为123和2;


线程抢占资源

 sleep():休眠,将当前线程暂停执行指令流,将执行机会(也就是CPU)给到其他线程,但是锁还是把握在对象手里;——>休眠时间结束回到就绪状态

wait():直接寄,调用这个方法代表你的线程暂停执行,锁也执行放弃了,线程进入等待池(wait pool),调用notify方法可以换新等待池中的线程——>然后进入等锁池,重新获得锁之后就可以恢复就绪状态;

yield():让相同优先级,或者优先级更高的线程之间能够起到同一起跑线上,或者说属于高风亮节的行为,让别人先上(优先级>=);

abstract和final

final修饰的,编译期间直接确定,所以说被final修饰的类是不能被继承的;

补充:final

首先要区分final用的是基本数据类型还是引用数据类型

1.基本数据类型:值不可再变,在编译时期就确定——>联想到类加载中的链接时期中的分析阶段

2.引用数据类型:不可指向不同的对象,但是对象中的值是可以改变的;

 

而abstract是抽象类只能被继承,而且子类必须实现所有的抽象方法;

Java类加载器

引导类加载器(bootstrap class loader):

它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。主要负责jdk_home/lib目录下的核心api 或 -Xbootclasspath 选项指定的jar包装入工作(其中的jdk_home是指配置jdk环境变量是java_home的配置路径,一般是jdk/jre所在目录)。

扩展类加载器(extensions class loader):

它用来加载 Java 的扩展库。Java虚拟机的实现会提供一个扩展库目录,扩展类加载器在此目录里面查找并加载 Java 类,主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。

系统类加载器(system class loader):

它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。主要负责CLASSPATH/-Djava.class.path所指的目录下的类与jar包装入工作.

除了系统提供的类加载器以外,开发人员可以通过继承java.lang.ClassLoader类的方式实现自己的类加载器,从而进行动态加载class文件,以满足一些特殊的需求,这体现java动态实时类装入特性。

除了引导类加载器之外,所有的类加载器都有一个父类加载器,通过getParent()方法可以得到。对于系统提供的类加载器来说,系统类加载器的父类加载器是扩展类加载器,而扩展类加载器的父类加载器是引导类加载器;对于开发人员编写的类加载器来说,其父类加载器是加载此类加载器 Java 类的类加载器。因为类加载器 Java 类如同其它的 Java 类一样,也是要由类加载器来加载的。一般来说,开发人员编写的类加载器的父类加载器是系统类加载器。类加载器通过这种方式组织起来,形成树状结构。树的根节点就是引导类加载器。下图中给出了一个典型的类加载器树状组织结构示意图,其中的箭头指向的是父类加载器。

反射

1. 程序编译时,会生成一个字节码文件,后缀为.class,2.当我们new一个对象时,jvm会从本地加载相应的.class文件在内存中,同时产生一个Class对象,这个Class对象无论new 多少个本地对象,都只会生成一个,这个Class对象所属的位置为java.lang,排除A。3.反射时,运用的是内存中生成的Class对象,然后反推到字节码文件中,再获取相应对象的方法或者属性,但是并不会动态修剪字节码文件。关于F的效率问题,主要是寻找对应的字节码文件所需的时间

反射是不能实现对字节码文件的修改,主要是通过instanceKlass获得字节码文件中的内容;反射会造成效率降低;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fairy要carry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值