美文网首页程序员
Java基础之变量

Java基础之变量

作者: 暴走的朝天椒 | 来源:发表于2018-06-26 17:09 被阅读79次

学习目标

1、介绍变量命名规则、变量在JVM中的体现
2、介绍Java变量的类型(基本数据类型、引用类型)
3、Java基础数据溢出分析
4、深入理解Java引用类型的级别(强引用、软引用、弱引用、虚引用)
5、讨论Number类(java.lang包中)及其子类
6、包装类与基本数据类型的区别

Java版本

JDK8

介绍Java语言的几种变量

Java语言定义的几种变量
1、实例变量(非静态字段)
2、静态变量(类字段)
3、局部变量
4、常量

package com.sample;
public class VariableSample {
    private String p1; // 实例变量
    private static String p2; // 类变量
    private static final String p3 = "p3"; // 常量

    public void play(){
        int a = 1; // 基本类型 - 局部变量
        String b = "b"; // 引用类型 - 局部变量
    }
}

变量命名规则
1、变量名称区分大小写。惯例是用字母开头,而不是“$” “_”,虽然他们在技术上是合法的。
2、字母开头,后续字符可能是 数字字母下划线美元符号。
3、选择的名称不能是 关键字保留字
4、如果你选择的名字只包含一个单词,则全部用小写字母拼出来。如果它包含多个单词,请将每个后续单词的首字母大写。

变量在JVM中的体现
堆:可供各个线程共享的运行时内存区域,也是所有类实例和数组对象分配内存的区域;因此 在存放实例变量 和 类变量时,要考虑线程安全问题。
栈:用于保存局部变量的值,包括:1、用于保存基本类型的值 2、保存类的实例,即堆对象的引用。因为每个java虚拟机线程都有自己私有的Java虚拟机栈,因此 局部变量是线程安全的。
运行时常量池:每一个运行时常量池,都在java虚拟机的方法区中分配。

Java变量的类型

1、基本数据类型
2、引用类型(reference type)

Java基本数据类型

基本数据类型 二进制位数 默认值 使用范围
byte 8 0 -128~127
short 16 0 -32768~32767
int 32 0 -2 31~2 31 -1
long 64 0 -2 63~2 63 -1
float 32 0.0f 此类型不用于精确值,例如货币。为此,您需要改为使用 java.math.BigDecimal
double 64 0.0d 此数据类型不应用于精确值,例如货币。为此,您需要改为使用 java.math.BigDecimal
boolean 1 false 只有两个可能的值:true和false
char 16 '\u0000' 它的最小值为'\u0000'(或0),最大值为'\uffff'(或65,535)

Java基础数据溢出分析
以byte为例,byte的数值是-128~127

package com.sample;
public class NumberSample {
    public static void main(String[] args){
        byte a = (byte)128;
        System.out.println(a);
    }
}

输出结果:-128

那么计算机是如何计算溢出数据的呢?
1、 byte是8位的二进制,因此将128转换为8位的二进制源码:1 0000000
2、 将原码转换为反码

符号位 数值位
原码 1 0000000
反码 1 1111111

3、 计算补码,反码 + 1


image.png

Java虚拟机中有三种引用类型
1、类类型(class type)
2、数组类型(array type)
3、接口类型(interface type)
这些引用类型的值分别指向动态创建的类实例、数组实例 和 实现了某个接口的类实例 或 数组实例。

深入理解java引用类型的级别

当内存空间还足够时,则能保留在内存之中;如果内存空间在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能都符合这样的应用场景。因此在JDK1.2之后,将引用分为下面四种级别,这四种引用强度由强到弱。
1、 强引用(Final Reference)
2、 软引用(Soft Reference)
3、 弱引用(Weak Reference)
4、 虚引用(Phantom Reference)

image.png

强引用(Final Reference)
1、 类似 Object obj = new Object(); 这类的引用
2、 只要强引用还存在(a、判断对象的引用数量 b、可达性分析算法判断对象的引用链是否可达),垃圾收集器永远不会回收掉被引用的对象。
3、 JVM宁愿抛出OOM异常,也不会回收还存在的强引用所指向的对象。

FinalReference.java源码

package java.lang.ref;

/**
 * Final references, used to implement finalization
 */
class FinalReference<T> extends Reference<T> {

    public FinalReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }
}

强引用只有一个构造函数,根据所给对象和队列构造一个强引用。

软引用(Soft Reference)
1、软引用用来描述一些有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够内存,才会抛出内存溢出异常。
2、这点很好的解决了OOM问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。

例子:

package com.sample;

import java.lang.ref.SoftReference;

public class ParamSample {
    public static void main(String[] args)
    {
        SoftReference softReference = new SoftReference(new String("hello world")); // 软引用
        System.out.println(softReference.get());
    }
}

弱引用(Weak Reference)
弱引用用来描述非必须对象,它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。

例子:

package com.sample;

import java.lang.ref.WeakReference;

public class ParamSample {
    public static void main(String[] args)
    {
        WeakReference weakReference = new WeakReference(new String("hello world"));
        System.out.println(weakReference.get()); // 垃圾回收之前,获得弱引用的对象
        System.gc(); // 垃圾回收
        System.out.println(weakReference.get()); // 垃圾回收之后,获得弱引用的对象
    }
}

虚引用(Phantom Reference)
1、 虚引用是最弱的一种引用关系。一个对象是否由虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。
2、 虚引用必须和引用队列关联使用。

例子:

package com.sample;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

public class ParamSample {
    public static void main(String[] args)
    {
        ReferenceQueue referenceQueue = new ReferenceQueue();
        PhantomReference phantomReference = new PhantomReference(new String("hello world"),referenceQueue);
        System.out.println(phantomReference.get());
    }
}

讨论Number类(java.lang包中)及其子类

大部分时间在代码中都使用基本数据类型,然而为了代码的灵活性,Java平台为每种基本数据类型提供包装类。

image.png
注意:BigDecimal并BigInteger用于高精度计算。AtomicInteger并AtomicLong用于多线程应用程序。

有如下原因要使用Number对象而不是原始数据:
1、通常用于处理数字集合。
2、要使用类定义的常量(如MIN_VALUE和)MAX_VALUE,它们提供数据类型的上限和下限。
3、 使用类方法将值转换为其他基本类型以及从其他基本类型转换值,转换为字符串和从字符串转换,以及在数字系统(十进制,八进制,十六进制,二进制)之间进行转换。
综上所述:当需要对数据做一些处理时,可以使用Number类及其子类提供的一些方法,以免重复造轮子。

自动装箱

自动装箱是Java编译器在基元类型和它们相应的对象包装类之间进行的自动转换。例如,将int转换为Integer,double转换为Double等等。

Java编译器在原始值为以下情况时应用自动装箱:
1、作为参数传递给期望相应包装类的对象的方法。
2、分配给相应包装类的变量。

拆箱

将包装类型(Integer)的对象转换为其相应的基元(int)值称为拆箱

Java编译器应用拆箱:
1、作为参数传递给需要相应基元类型值的方法。
2、分配给相应基元类型的变量。

包装类 与 基本数据类型的区别
1、包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是。
2、包装类型是引用的传递,基本类型是值的传递。
3、声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间 。
4、存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们 。
5、初始值不同,int的初始值为 0 、 boolean的初始值为false 而包装类型的初始值为null。

相关文章

网友评论

    本文标题:Java基础之变量

    本文链接:https://www.haomeiwen.com/subject/ksqyyftx.html