java基础一点也不基础

(新建的群1039047324,欢迎对技术感兴趣的朋友加入,群内可以接私活,聊技术,分享工作中容易踩的坑,以及如何避免踩坑,分享最新架构视频)

1 创建对象的有哪几种方式
创建对象是否一定要通过构造器,当然不是。

1)  通过new 创建对象。这种方法需要用到构造器

    Demo demo1=new Demo();Java String类为什么是final的
    Demo demo2=new Demo(1,"有参构造器");

2) 通过反射 newInstance()创建对象。这种方法用到构造器

  Demo demo2=(Demo) Class.forName("Demo").newInstance();

3) 通过object类的clone方法。需要实现Cloneable接口,重写object类的clone方法。无论何时我们调用一个对象的clone方法,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone方法创建对象并不会调用任何构造函数。

  Demo demo4=(Demo) demo2.clone();

4) 反序列化。java 中常常进行 JSON 数据跟 Java 对象之间的转换,即序列化和反序列化。
当我们序列化和反序列化一个对象,JVM会给我们创建一个单独的对象,在反序列化时,JVM创建对象并不会调用任何构造函数。为了反序列化一个对象,我们需要让我们的类实现Serializable接口,虽然该接口没有任何方法。不会调用任何构造函数。

2 Java String类为什么是final的 

  1. 为了实现字符串池
  2. 为了线程安全
  3. 为了实现String可以创建HashCode不可变性

    首先你要理解final的用途,在分析String为什么要用final修饰,final可以修饰类,方法和变量,并且被修饰的类或方法,被final修饰的类不能被继承,即它不能拥有自己的子类,被final修饰的方法不能被重写, final修饰的变量,无论是类属性、对象属性、形参还是局部变量,都需要进行初始化操作。

在了解final的用途后,在看String为什么要被final修饰:主要是为了”安全性“和”效率“的缘故。

final修饰的String,代表了String的不可继承性,final修饰的char[]代表了被存储的数据不可更改性。但是:虽然final代表了不可变,但仅仅是引用地址不可变,并不代表了数组本身不会变,请看下面图片。

 

如果字符串是可变的,那么会引起很严重的安全问题。譬如,数据库的用户名、密码都是以字符串的形式传入来获得数据库的连接,或者在socket编程中,主机名和端口都是以字符串的形式传入。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符串指向的对象的值,造成安全漏洞。


    因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。


    因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。


   字符串常量池,在大量使用字符串的情况下,可以节省内存空间,提高效率,String不可变性是最基本的一个前置条件。

 

3 反射中,Class.forName和classloader的区别?

Java中class是如何加载到JVM中的:
1.class加载到JVM中有三个步骤
    装载:(loading)找到class对应的字节码文件。
    连接:(linking)将对应的字节码文件读入到JVM中。
    初始化:(initializing)对class做相应的初始化动作。
2.Java中两种加载class到JVM中的方式
    1:Class.forName(“className”);
        其实这种方法调运的是:Class.forName(className, true, ClassLoader.getCallerClassLoader())方法
        参数一:className,需要加载的类的名称。
        参数二:true,是否对class进行初始化(需要initialize)
        参数三:classLoader,对应的类加载器
    2:ClassLoader.laodClass(“className”);
        其实这种方法调运的是:ClassLoader.loadClass(name, false)方法
        参数一:name,需要加载的类的名称
        参数二:false,这个类加载以后是否需要去连接(不需要linking)
        
    两种方式的区别
        forName("")得到的class是已经初始化完成的
        loadClass("")得到的class是还没有连接的
        一般情况下,这两个方法效果一样,都能装载Class。
        但如果程序依赖于Class是否被初始化,就必须用Class.forName(name)了。

比如:连接数据库

    java使用JDBC连接数据库时候,我们首先需要加载数据库驱动。
    Class.forName(“com.mysql.jdbc.Driver”);//通过这种方式将驱动注册到驱动管理器上
    Connection conn = DriverManager.getConnection(“url”,“userName”,“password”);//通过驱动管理器获得相应的连接
    查看com.mysql.jdbc.Driver源码:

public class Driver extends NonRegisteringDriver
  implements java.sql.Driver
{
    //注意,这里有一个static的代码块,这个代码块将会在class初始化的时候执行
  static
  {
    try
    {
        //将这个驱动Driver注册到驱动管理器上
      DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
      throw new RuntimeException(“Can’t register driver!”);
    }
  }
}

Class.forName(“com.mysql.jdbc.Driver”)方法以后,他会进行class的初始化,执行static代码块。
    也就是说class初始化以后,就会将驱注册到DriverManageer上,之后才能通过DriverManager去获取相应的连接。
    但是要是我们使用ClassLoader.loadClass(com.mysql.jdbc.Driver)的话,不会link,更也不会初始化class。
    相应的就不会回将Driver注册到DriverManager上面,所以肯定不能通过DriverManager获取相应的连接。

4 java反射原理 (反射是框架设计的灵魂)

1 ) JAVA反射机制是在运行状态中

对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法和属性;

这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

2) 反射提供的功能:

在运行时判断任意一个对象所属的类
    在运行时构造任意一个类的对象
    在运行时判断任意一个类所具有的成员变量和方法
    在运行时调用任意一个对象的方法
(要想解剖一个类,必须先要获取到该类的字节码文件对象(class)。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.)

3) 关于class对象和这个class类

Class对象的由来是将class文件读入内存,并为之创建一个Class对象

4) class类 :代表一个类,是Java反射机制的起源和入口
用于获取与类相关的各种信息, 提供了获取类信息的相关方法
    Class类继承自Object类
    Class类是所有类的共同的图纸
    每个类有自己的对象,同时每个类也看做是一个对象,有共同的图纸Class,存放类的结构信息,能够通过相应方法取出相应的信息:类的名字、属性、方法、构造方法、父类和接口。

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型)
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。

没有公共的构造方法,方法共有64个太多了。

5) 反射的使用场景
    Java编码时知道类和对象的具体信息,此时直接对类和对象进行操作即可,无需反射。如果编码时不知道类或者对象的具体信息,此时应该使用反射来实现。比如类的名称放在XML文件中,属性和属性值放在XML文件中,需要在运行时读取XML文件,动态获取类的信息。在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息。

6) 获取反射入口(class对象)的三种方法

要想操作反射,必须先拿到反射的入口

1,通过通过Class.forName("全类名")

 2,对象.getClass()

3,类名.class (任何数据类型(包括基本数据类型)都有一个“静态”的class属性)

注意:在运行期间,一个类,只有一个Class对象产生。

3种方式常用第1种,第2种对象都有了还要反射干什么。第3种需要导入类的包,依赖太强,不导包就抛编译错误。一般都第1种,一个字符串可以传入也可写在配置文件中等多种方法。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习Java基础知识可以按照以下步骤进行: 1. 学习编程基础:了解编程的基本概念、语法和逻辑。可以从学习其他编程语言开始,比如Python或C,这将帮助你掌握一些通用的编程概念。 2. 学习Java语言特性:Java是一种面向对象的编程语言,你需要学习类、对象、继承、多态等概念。可以通过阅读教材或参加在线教育平台上的课程来学习。 3. 安装和设置Java开发环境:下载并安装Java Development Kit(JDK),这是Java开发的基础工具包。然后设置Java环境变量,以便在命令行或集成开发环境(IDE)中使用Java。 4. 学习Java核心库:Java有很多内置的类和方法可以帮助你开发应用程序。学习Java核心库可以帮助你理解并使用这些功能。包括IO操作、集合框架、多线程等。 5. 练习编写代码:通过编写实际的Java程序来巩固所学知识。可以从简单的程序开始,逐渐增加难度,例如编写控制台应用程序、图形用户界面(GUI)应用程序或网络应用程序。 6. 参与项目或实践:通过参与开源项目、完成编程挑战或实践项目来提升你的Java编程能力。这将帮助你应用所学知识,并加深理解。 7. 持续学习和探索:Java是一门广泛应用的编程语言,有很多不同的应用领域和框架。持续学习和探索新的技术、框架和最佳实践,以保持自己的竞争力。 记住,学习编程需要时间和耐心。坚持练习,解决问题时要多思考,多查阅文档和参考资料,提高自己的编程能力。祝你学习Java的旅程愉快!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值