谈谈什么是Java?

这个问题我花了挺长时间去整理,这类知识没啥实际用处,却是必须知道的。我从3个方面去解释这个问题:思想、JDK、数据类型。

1. Java面向对象的思想和三大特性:

在Java中有句话叫‘万物皆对象’,事物都有自己的属性和行为,而我们将其编写到类中,用数据类型表述属性,用方法表述行为,这就是面向对象思想。

封装:

       封装就是不让人直接修改类中成员属性,不能直接访问类中方法,所以对属性封装要用private修饰,并提供get\set()用于取值和赋值操作;而对方法的封装,一般只对外提供一个接口,接口是一种规范,它规定了方法的返回值、参数和方法名,方法的具体实现则在其实现类中。

继承:

       继承就是继承父类的属性及行为,但要注意构造器不能被继承,所以不能被重写,但能被重载;非私有的父类成员变量可以被子类覆盖,可以用super()调用父类成员变量;还有一点值得注意,父类被private修饰的属性和方法,不能被继承,但是当父类提供了该属性的get\set()方法时,子类对象又可以通过set\get()方法对父类私有属性进行赋值和取值操作,相当于变相的拥有了这些属性,说实话这一点我有些困惑。

多态:

       多态的前提:父类的引用指向子类的对象、重写、继承,我们要注意多态时,父类的引用只能调用父类中存在的属性及方法,不能调用子类的特有方法,但父类方法被子类重写后,父类引用调用的是子类的方法。

 

2. Java的跨平台及JDK简析:

跨平台:无论是Windows还是Unix系统,只要安装了Jdk,就可以运行Java程序。

Jdk简析:

      Jdk是Java的开发工具,其中包含了编译器、Jar包等实用工具 ;还包括了Java的运行环境Jre ;而Jre中包含了Java的核心类库和Jvm。

Jvm简析:

      Jvm就是Java虚拟机,当我们编译后的.class文件进入Jvm后,会被Class Loader类加载器加载,然后交由Jvm执行引擎执行,在程序执行过程中,Jvm会用一段空间来存储程序执行过程中所需的数据和相关信息,这段空间即Jvm内存。

Jvm内存简析:

      Jvm内存包括:Java栈、堆、本地方法栈、方法区、程序计数器。

      程序计数器:其保存当前执行的指令地址,CPU在同一时间只会执行一条线程中的指令,所以说程序计数器是每个线程所私有的。要注意在Jvm规范中,如果线程执行的是非native方法,则程序计数器中保存的是指令,反之保存的值是undefined。

     Java栈:Java栈中存放的是一个个栈帧,每个栈帧对应一个被调用的方法,栈帧中包括:局部变量表(即方法中声明的非静态变量和方法形参,对于基本数据类型的变量是直接储存值,对于引用数据类型的变量存储的是其引用)、操作数栈、指向运行时常量池的引用(方法执行时可能需要用到类中的常量,所以需要有一个引用指向运行时常量池)、方法返回地址;要注意Java栈是每个线程都有的。

     本地方法栈:与Java栈类似,区别就是一个服务于Java方法,一个服务于Native Method;Native Method就是一个Java调用非Java代码的接口。

     堆:堆中存放的是对象本身,其引用放在栈中,堆是被所有线程共享的

     方法区:首先它与堆一样被所有线程共享,在方法区中存储了类的信息(类名称、方法信息、字段信息)、静态变量、常量池以及编译器编译后的代码等。

Jvm的垃圾回收机制及调优:

  1. Jvm调优是通过设置jvm参数进行优化,比如设置jvm内存、堆内存等。
  2. Jvm的垃圾回收是指不定期回收没有被引用对象所占内存,JVM采用分代垃圾回收。在JVM的内存空间中把堆空间分为年老代和年轻代。将大量创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象。年轻代中又被分为Eden区、和两个Survivor区。新的对象分配是首先放在Eden区,Survivor区作为Eden区和Old区的缓冲,在Survivor区的对象经历若干次收集仍然存活的,就会被转移到年老区。

 

         简单讲,就是生命期短的对象放在一起,将少数生命期长的对象放在一起,分别采用不同的回收策略。生命期短的对象回收频率比较高,生命期长的对象采用比较低回收频率。

 

2. Java的数据类型:

1. 基本数据类型:

    byte:数据范围是-128~127,二进制位数是8,对应包装类是Byte

    short:最大数据存储量是65536,范围是-32768~32767,二进制位数是16,对应包装类是Short

    int:数据范围是负的2的31次方到正的2的31次方-1,二进制位数是32,对应包装类是Integer

    long:数据范围是负的2的63次方到正的2的63次方-1,赋值时后面必须加l或L,二进制数位是64,对应包装类是Long

    float:数据范围是3.4e-45~1.4e38,赋值时后面必须加f或F,二进制位数是32;对应包装类是Float浮点型的最大最小值是科学计数法表示的,结尾的e+数字表示e前的数字乘以10的多少次方

    double:数据范围是4.9e-324~1.8e308,二进制位数是64,对应包装类是Double

    boolean:只有true和false两个取值,对应包装类是Boolean,注意在数据库中,用数字1表示true,数字0表示false

    char:存储Unicode码,用单引号赋值,二进制位数是16,对应包装类是Character

    引用数据类型:String类、接口、数组、枚举、标注

2. 基本数据类型的包装类?

    Java的包装类都实现了常量池技术;

    Java5.0开始,实现了基本数据类型和对应包装类的自动转换,它有很多优势,比如集合中存储的都是对象元素,比如int的默认值是0,而Integer的默认值为null,这样就可以区分0和null。

3. 数据类型之间的转换?

   (1)数据类型之间的自动转换和强制转换:

       强制转换是指大的数据类型向小的数据类型转换,强制转换可能会出现溢出或精度丢失问题。

       自动转换是小的数据类型向大的数据类型进行转换,如:byte b;int i=b; long l=b; float f=b; double d=b;注意char类型向整形转换时会转换为对应的ASCII码值,如char c=c;int a=c;对于char、short、byte三种类型而言,属平级,需要强制转换;最后浮点型转整型是直接舍弃小数点后面部分取整,会丢失精度。另外int到float,long到float,long到double转换都有可能丢失精度;而且float与double无论自动还是强制都可能出现精度丢失问题。

        注1:我们通过程序决定float转double的结果:

                 float c = 1.155f;

                 double b = c;

                 System.out.println(c==b);//true

                 System.out.println(c);//1.155

                 System.out.println(b);//1.154999...

           

       2float的有效小数位6-7位;double的有效小数位15-16;这就是精度可能丢失的原因,所以要想不丢失精度,我们要注意我们的数据大小。

              float:1bit(符号位) 8bits(指数位) 23bits(尾数位)
                        精度是由尾数的位数来决定的
              float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,也即float的精度为6~7位有效数字;注意这里的6~7位是有效小数位(大的数你先需要转换成小数的指数形式,例如:8317637.5,其有效小数位:8.3176375E6,七位),而有效位(从第一个不为0的开始数)是7~8位,是包括整数位的,像8317637.5,你不转换,则要从有效位的角度来看,有8位有效位。

  (2) 通过对应的包装类进行转换,各个包装类中总有xxValue()方法

  (3) String与其他类型转换:

        转String:

                调用类的toString()方法

                调用String的valueOf()方法

                自动转换:“”+X

         String转:

                如:String s = 3;

                调用各个包装类的parseXXX(String str)方法

                如:String st = str;

                调用各个包装类的valueOf(String st,int index)方法

 

 (4)【扩展】Date类与String的转换?

        Date date = new Date();

        SimpleDateFormat sd=new SimpleDateFormat("yy-MM-dd");

        String str = sd.format(date);

        Date d = sd.parse("18-05-11");

4. 数据类型之间的运算?

    Java的数据运算,我们应该保持在同类型之间,否则会出现意想不到的错误;我们还需要注意下面的几个运算规则:当byte、short、char类型的值参与时,会自动转int类型;当运算中有一个是long、float、duoble类型之一时,计算结果分别是long、float、duoble类型,我们需要注意float和double不能表示精确值,所以运算时需要先化整运算再化浮点接收。

 

就这些了,有问题还请指出,一起进步。

猜你喜欢

转载自blog.csdn.net/weixin_38943098/article/details/87873034