Java基础1

1 const和goto是Java的保留字,不是关键字

2 基本数据类型占用字节数

    整数类型:byte(1) short(2) int(4) long(8)

  浮点数类型:float(4) double(8)

  字符类型:char(2)

  布尔类型:boolean(1)

  整数默认为int类型,浮点数默认为double类型,长整型要加l,单精度型要加f

3 常量的类型

  整数常量

  浮点数常量

  字符常量:'a'

  字符串常量:"abc"

  布尔常量:true false

  空常量:null

4 数据类型向上转化时可能损失精度,编译器会报错

byte b1=3,b2=4,b;
b=b1+b2;//整型变量赋给一个字符型变量可能会损失精度,所以编译不通过
b=3+4;//这里是常量运算,会先计算出结果,看结果是否在byte类型所表示的数的范围内,在的话就可以赋值,编译可以通过

      总结:变量必须在运行的时候才能确定,而常量表达式在运行之前就会先计算出结果

  下面的代码同理

short s=1;s = s+1;//有问题,从int到short可能会丢失精度
short s=1;s+=1;//没有问题,+=隐藏了一个强制类型转换,s+=1相当于s = (s的数据类型)(s + 1);

5 把不在精度范围内的byte值强转存储

  byte b=130;//会报错

  byte b=(byte)130;//-126

  计算机中数据都是以补码方式运算的

  正数130的原码是10000010

  把10000010看成补码的话,它的原码就是11111110 即-126

6 浮点数在内存中的存储方式:

  float类型数据占用4个字节,由底数m和指数e组成

  指数部分占8bit,可以表示0-255之间的数值,但指数有正有负,所以IEEE规定这里得到的指数必须减去127才是真正的指数

  所以float类型指数范围为-126到128

  底数部分占24bit,最高位为符号位,所以有23bit来存储值

  综上,浮点数格式:SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

  例如17.625在内存中的存储:

  17.625的二进制表示为10001.101

  将10001.101右移,直到只有一位整数部分,即1.0001101*2^4

  由于整数部分一定是1,所以只记录小数部分就可以,即0001101就是底数

  指数为4,必须加上127,所以为131,也就是10000011

  符号位是0

  所以17.625存储方式为01000001 10001101 00000000 00000000

7 &&与&的区别是&&有短路效果

8 switch(expression)中的表达式可以是byte short int char,JDK5之后可以是枚举,JDK7之后可以是String

9 数组初始化

   //1、动态初始化 只给长度,系统给出默认值
    int[] arr=new int[3];
   //2、静态初始化 给出值,系统决定长度
    int[] arr=new int[]{1,2,3};
   //或者
    int[] arr={1,2,3};

10 内存分配

  A:栈 存储局部变量
  B:堆 存储所有new出来的
  C:方法区(面向对象部分详细讲解)
  D:本地方法区(系统相关)
  E:寄存器(CPU使用)

    注意:
      a:局部变量 在方法定义中或者方法声明上定义的变量。
      b:栈内存和堆内存的区别
        栈:数据使用完毕,就消失。
        堆:每一个new出来的东西都有地址
        每一个变量都有默认值
          byte,short,int,long 0
          float,double 0.0
          char 'u0000'
          boolean false
          引用类型 null
      c:数据使用完毕后,在垃圾回收器空闲的时候回收。

11 二维数组

  

12 成员变量和局部变量的区别

  (1)在类中的位置不同
    成员变量:类中方法外
    局部变量:方法定义中或者方法声明上(其实就是方法的参数)
  (2)在内存中的位置不同
    成员变量:在堆中
    局部变量:在栈中
  (3)生命周期不同
    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
  (4)初始化值不同
    成员变量:有默认值
    局部变量:没有默认值,必须定义,赋值,然后才能使用

13 构造方法没有返回值类型,连void都不能有,没有返回值

14 静态方法中没有this对象,静态方法内只能访问静态成员

15 静态变量和成员变量的区别

  A:所属不同
    静态变量:属于类,类变量
    成员变量:属于对象,对象变量,实例变量
  B:内存位置不同
    静态变量:方法区的静态区
    成员变量:堆内存
  C:生命周期不同
    静态变量:静态变量是随着类的加载而加载,随着类的消失而消失
    成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失
  D:调用不同
    静态变量:可以通过对象名调用,也可以通过类名调用
    成员变量:只能通过对象名调用

16 static内存图

17 执行顺序:静态代码块>构造代码块>构造方法

18 this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。

  this:代表当前类的对象引用
  super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)

    场景:
    成员变量:
      this.成员变量
      super.成员变量
    构造方法:
      this(...)
      super(...)
    成员方法:
      this.成员方法
      super.成员方法

19 继承的注意事项

  子类不能继承父类的私有成员

  子类不能继承父类的构造方法,但是可以通过super去访问

  子类中所有的构造方法默认都会访问父类无参的构造方法,因为子类要继承父类的数据,还可能会使用父类中的数据,所以子类初始化前,一定要先完成父类的初始化,事实上子类每一个构造方法的第一句都是super(),即使没有写super也会隐式调用super

20 关于抽象类

子类的构造方法默认会去访问父类的无参构造方法,是为了子类访问父类数据的初始化,如果父类中没有无参构造方法,子类中需要通过super关键字调用父类中带参的构造方法,或者是子类通过this调用本身的其他构造,但是一定会有一个去访问了父类的构造,再或者让父类提供无参构造

抽象类的实例化其实是靠具体的子类实现的。是多态的方式Animal a = new Cat();

21 final修饰的变量只能在定义的时候或者在构造函数中初始化赋值

22 多态的弊端:子类赋给父类的对象不能使用子类特有的方法

class Fu {
    public void show() {
        System.out.println("show fu");
    }
}
class Zi extends Fu {
    public void show() {
        System.out.println("show zi");
    }    
    public void method() {
        System.out.println("method zi");
    }
}
class DuoTaiDemo3 {
    public static void main(String[] args) {
        Fu f = new Zi();
        f.show();
        f.method();
    }
}

如果想要访问,可以将f向下转型,转换成子类对象,即

        Zi z = (Zi)f;
        z.show();
        z.method();

但前提是f一定要能转成Zi类型的子类,否则会有ClassCastException类型转换异常

23 Scanner

System类下面有一个静态而且是final的成员,类型是标准输入流,对应键盘的输入

public static final InputStream in;

Scanner类的构造函数标准输入流类型的重载

public Scanner(InputStream source){
   ... 
}

所以Scanner类的实例化对象如下:

Scanner sc=new Scanner(System.in);

Scanner类提供了多组hasNextXxx/nextXxx的实例化方法,最常用的是nextLine(获取一个字符串)和nextInt(获取一个整型值),例如

public class ScannerDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        if (sc.hasNextInt()) {
            int x = sc.nextInt();
            System.out.println("x:" + x);
        } else {
            System.out.println("你输入的数据有误");
        }
    }
}

24 String类型的几种构造

  1 空构造

    String s1=new String();

  2 字节数组转成字符串

    byte[] b={97,98,99,100,101};

    String s2=new String(b);

    System.out.println(s2.length());//5

  3 字节数组的一部分转成字符串

    byte[] b={97,98,99,100,101};

    String s3=new String(b,1,3);//从第1个开始转,长度为3

  4 字符数组转成字符串

    char[] chs = { 'a', 'b', 'c', 'd', 'e', '爱', '林', '亲' };

    String s4 = new String(chs);

    System.out.println(s4.length());//8

  5 字符数组的一部分转成字符串

    char[] chs = { 'a', 'b', 'c', 'd', 'e', '爱', '林', '亲' };

    String s5=new String(chs,2,4);//从第2个开始转,长度为4

  6 字符串常量转为字符串

    String s6=new String("abcde");

  7 字符串的字面值也可以看成是一个字符串对象

    String s7="abcde";

25 String s = new String("hello")和String s1 = "hello";的区别 ??

  前者会创建2个或者1个对象,后者创建1个或者0个对象

  通过new创建的对象都在堆内存中,所以new String()在堆中创建了一个对象,而这个构造又传入了"hello"这个字符串常量,创建这个字符串常量的时候会在内存方法区中的字符串常量池里面寻找,如果没有的话才创建,如果有的话将常量池中的字符串常量的地址赋给new String(),现在肯定在常量池中找不到"hello"这个字符串常量,因此会创建这个"hello"字符串常量并放到常量池中,然后再将new String()这个对象在堆中的地址赋给s。

  接下来再通过String s1="hello";创建字符串的时候,没有通过new来创建,所以直接在字符串常量池里面寻找,结果一定能找到之前new String()创建的那个"hello",所以再将"hello"这个字符串常量的地址赋给s1,目前s存放的时new String()在堆中的地址,s1中存放的是"hello"在字符串常量池中的地址,所以s和s1一定不一样。

26 String相关方法

  String s="JavaSE"; 

  byte[] b=s.getBytes();//字符串转为字节数组

  char[] c=s.toCharArray();//字符串转为字符数组

  String ss=String.valueOf(c);//字符数组转为字符串 静态方法

  int i=100;

  String sss=String.valueOf(i);//整型转为字符串 静态方法

27 String和int之间相互转换

  int->String

    int n=100;

    //String s1=""+n;

    //String s1=String.valueOf(n);

    //String s1=Integer.toString(n);

  String->int

    String s="100";

    //int x=new Integer(s).intValue();

    //int x=Integer.parseInt(s);

28 StringBuffer

  String s="aaa"+"bbb"+"ccc";这样一条语句将会在字符串常量池中会产生"aaa" "bbb" "ccc" "aaabbbccc"四个字符串,但是前三个都是没用的,所以是用String的时候会造成内存空间的浪费,而且操作还很耗时

  StringBuffer是线程安全的可变字符串,StringBuffer和String的区别在于前者的长度和内容可变,后者不可变,如果使用前者做字符串的拼接,不会浪费太多的资源

  构造方法:

  StringBuffer()

  StringBuffer(int capacity)//指定容量

  StringBuffer(String str)//指定内容

  capacity / length

  StringBuffer sb=new StringBuffer();

  System.out.println(sb);//什么也没有

  System.out.println(sb.capacity());//容量,初始为16

  System.out.println(sb.length());//长度,初始为0

  StringBuffer sb2=new StringBuffer("hello");

  System.out.println(sb2.capacity());//21,原因可以看StringBuffer的相关构造方法

  append——可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身

  StringBuffer sb=new StringBuffer();

  sb.append("hello");

  sb.append(34.5);

  sb.append(true);

  System.out.println(sb);//hello34.5true

  //append可以链式调用

  sb.append("abc").append("cde").append("fgh");

  insert——在指定位置把任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身

  StringBuffer sb=new StringBuffer("abccdefgh");

  sb.insert(1,"myj");//amyjbccdefgh

  deleteCharAt(int index)——删除指定位置的字符,并返回本身

  delete(int start,int end)——不包含end,会返回本身

  replace(int start,int end,String str)

  reverse()

  substring(int start) substring(int start,int end)——返回String类型,不是本身

29 String和StringBuffer之间的转换

  //String-->StringBuffer

  String s="hello";

  //方式一:通过构造方法

  StringBuffer sb=new StringBuffer(s);

  //方式二:通过append方法

  StringBuffer sb2=new StringBuffer();

  sb2.append(s);

  //=================

  //StringBuffer-->String

  StringBuffer buffer=new StringBuffer("java");

  //方式一:通过构造方法

  String str=new String(buffer);

  //方式二:通过toString方法

  String str2=buffer.toString();

30 数组拼接成字符串

public static void arrayToString(int[] arr){
    StringBUffer sb=new StringBUffer();
    for(int i=0;i<arr.length;i++){
        if(i==arr.length-1){
            sb.append(arr[i]);
        }else{
            sb.append(arr[i]).append(",");
        }
    }
}

31 String StringBuffer StringBuilder的区别

  String是内容不可变的,后两者内容可变

  StringBuffer和StringBuilder之间的方法是相兼容的

  StringBuffer是同步的,数据安全,效率低

  StringBuilder是不同步的,数据不安全,效率高(适用于单线程,但单线程的情况很常见)

32 StringBuffer和数组的区别?

  StringBuffer可以append各种类型的数据,但是都会转换成String类型,而数组只能append一种类型的数据

33 String和StringBuffer类型形参

  String作为参数传递,效果和基本类型作为参数传递一样

public class StringBufferDemo {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "world";
        System.out.println(s1 + "---" + s2);// hello---world
        change(s1, s2);
        System.out.println(s1 + "---" + s2);// hello---world

        StringBuffer sb1 = new StringBuffer("hello");
        StringBuffer sb2 = new StringBuffer("world");
        System.out.println(sb1 + "---" + sb2);// hello---world
        change(sb1, sb2);
        System.out.println(sb1 + "---" + sb2);// hello---worldworld

    }

    public static void change(StringBuffer sb1, StringBuffer sb2) {
        sb1 = sb2;
        sb2.append(sb1);
    }

    public static void change(String s1, String s2) {
        s1 = s2;
        s2 = s1 + s2;
    }
}

34 数组查找和排序 

//冒泡排序————先将最大值放到最后面
public static void bubbleSort(int[] arr){
    for(int i=0;i<arr.length-1;i++){
        for(int j=0;j<arr.length-1-i;j++){
            if(arr[j]<arr[j+1]){
                int tmp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=tmp;
            }
        }
    }
}
//选择排序————先将最小值放到最前面
public static void selectSort(int[] arr){
    for(int i=0;i<arr.length;i++){
        for(int j=i+1;j<arr.length;j++){
            if(arr[i]>arr[j]){
                int tmp=arr[i];
                arr[i]=arr[j];
                arr[j]=tmp;
            }
        }
    }
}
//二分查找
public static int binarySearch(int[] arr,int value) {
    int min = 0;
    int max = arr.length-1;
    int mid = (min+max)/2;
    
    while(arr[mid] != value) {
        if(arr[mid] > value) {
            max = mid - 1;
        }else if(arr[mid] < value) {
            min = mid + 1;
        }
        
        if(min > max) {
            return -1;
        }
        
        mid = (min+max)/2;
    }
    
    return mid;
}

35 Calendar类

Calendar now = Calendar.getInstance(); 
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);//和js一样,month是从0-11
int date = now.get(Calendar.DATE);

Calendar c=Calendar.getInstance();
//相对于今天5年后的10天前
c.add(Calendar.YEAR,5);
c.add(Calendar.DATE,-10);

//set方法
c.set(2011,11,11);//和js一样,这里实际上设置的是12月

System.out.println(year + "年" + (month + 1) + "月" + date + "日");

36 Date DateFormat

Java中的Date和js中的Date一模一样

        //日期对象-->字符串
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String s = sdf.format(d);
        System.out.println(s);
        //字符串-->日期对象
        String str = "2008-08-08 12:12:12";
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date dd = sdf2.parse(str);
        System.out.println(dd);

37 Math

Java中的向上向下取整和js有区别

System.out.println("ceil:" + Math.ceil(12.34));//13.0
System.out.println("floor:" + Math.floor(12.34));//12.0

38 Random

* 构造方法:
* public Random():没有给种子,用的是默认种子,是当前时间的毫秒值
* public Random(long seed):给出指定的种子
*
* 给定种子后,每次得到的随机数是相同的。
*
* 成员方法:
* public int nextInt():返回的是int范围内的随机数
* public int nextInt(int n):返回的是[0,n)范围的内随机数

39 内部类

/*
    成员内部类:
        如何直接访问内部类的成员。
        外部类名.内部类名 对象名 = 外部类对象.内部类对象;
*/
class Outer {
    private int num = 10;
    
    class Inner {
        public void show() {
            System.out.println(num);
        }
    }
}

class InnerClassDemo3 {
    public static void main(String[] args) {
        //需求:我要访问Inner类的show()方法
        //Inner i = new Inner();
        //i.show();
        
        //格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
        Outer.Inner oi = new Outer().new Inner();
        oi.show();
    }
}
原文地址:https://www.cnblogs.com/zhaohuiziwo901/p/4990010.html