首页 > 编程语言 >动力节点javaSE笔记

动力节点javaSE笔记

时间:2023-01-22 22:45:26浏览次数:34  
标签:String int class System 笔记 public new javaSE 节点

目录

alt + insert IDEA新建代码,在代码中使用可以生成构造方法,tostring方法等。

Java 语言的软件开发工具包(Java Development Kit,简称JDK):它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

Java运行环境(Java Runtime Environment,简称JRE)是一个软件,JRE可以让计算机系统运行Java应用程序。

没有JDK的话,无法编译Java程序(指java源码.java文件),如果想只运行Java程序(指class或jar或其它归档文件),要确保已安装相应的JRE。

jdk jre img

javac.exe命令负责编译,java.exe命令负责运行

byte+short+char 做混合运算时,会各自先转换成int再做运算

除此之外,其它多种数据类型做混合运算的时候,最终的结果类型是“最大容量”对应的类型

public class test
{
    public static void main (String[] args)
    {
    	char c = 'a';
    	byte b = 1;
    	short s = 2;
    	long l = 10L;
        
		(c + b + s)	// int类型
		(b + c)	 // int类型
		(c + b + s + l)	// long类型
		(c + l)	// long类型
    }
}

switch 只支持 int 和 String 类型,如果case无break会出现穿透现象

case合并:

public class switchTest {
    public static void main(String[] args) {
        java.util.Scanner s = new java.util.Scanner(System.in);
        int num = s.nextInt;
        switch(num) {
        case 1: case 2: case 3:
        	System.out.println("aaa");
        	break;
        case 4:
             System.out.println("bbb");
             break;
        default:
             System.out.println("ccc");
        }
    }
}
调用方法:类名.方法名(其中在一个类中调用,类名可以省略)
方法重载条件:
  • 在一个类中
  • 方法名相同
  • 参数列表不同(至少满足以下一个条件即可)
    • 参数个数不同 eg(int a), eg(int a, int b)
    • 参数类型不同 eg(int a), eg(double d)
    • 参数顺序不同 eg(int a, double d), eg(double d, int a)

以下两种情况是方法重复,并非方法重载

/*返回值类型不同*/
public static int sum() {
    return 1;
}

public static double sum() {
    return 1.0;
}
/*修饰符类型不同*/
public static void w1() {
}

void w1() {
}
面向对象三大特征:
  • 封装
  • 继承
  • 多态
类 ---> [实例化] ---> 对象(实例)
对象 ---> [抽象] ---> 类
方法体内的变量是局部变量,局部变量需手动赋值
方法体外,类体内的变量是成员变量,可不手动赋值,未手动则自动赋默认值
JVM

实例化对象在栈中存储的是地址,这个地址是堆内存对象的内存地址

基本数据类型在栈中存储的是数据值

空指针异常:空引用访问" 实例相关的数据 (实例变量/实例方法) "
构造方法

作用:1、创建对象 2、给属性赋值

public class test {
    int num;
    String str;
    boolean age;
    
    public test() {
        //若类中无任何构造方法,则系统会默认创建一个无参构造方法,称为缺省构造器
    }
    public test(int a, String b, boolean c) {
        num = a;
        str = b;
        age = c;
    }
}
public class constructor {
    public static void main(String[] args) {
        test t1 = new test();	//通过new调用构造方法,也是在此时候初始化实例变量
        System.out.println(t1.num);
        System.out.println(t1.str);
        System.out.println(t1.age);
        //0		null	false
        test t2 = new test(111, "aaa", true);
        System.out.println(t1.num);
        System.out.println(t1.str);
        System.out.println(t1.age);
        //111	aaa		true
        System.out.println(t1);		//test@16d3586
        System.out.println(t2);		//test@154617c
    }
}
封装
第一步:代码私有化
第二步:一个属性对外提供两个get方法和set方法

不带static的方法被称为实例方法,实例方法调用时必须先new对象


get:

public 返回值类型 get+参数首字母大写(无参) {
	return xxx;
}

set:

public void set+参数首字母大写(一个参数) {
	xxx = 一个参数;
}
public class test {
    //以下实例的,都是与对象相关的,访问时采用“引用.”的方式,需要先new对象
    int x1;		// 成员变量中的实例变量,在new对象的时候初始化,存储在堆中
    
    public void m1() {	// 实例方法
        int y1;	// 局部变量,存储在栈中
    }
    
    //以下静态的,都是与类相关的,访问时采用“类名.”的方式,不需要new对象
    static int x2;	//成员变量中的静态变量,在类加载的时候初始化,存储在方法区中
    
    public static void m2() {	//静态方法
        int y2;	// 局部变量,存储在栈中
    }
}

静态代码块与实例代码块

public class test {
	static { // 静态代码块,在类加载时调用
		System.out.print("A");
	}
    
    { // 实例代码块,在构造方法执行之前调用
        System.out.print("B");
    }
    
    public static void main(String[] args) {
        System.out.print("C");
        new test();
        System.out.print("D");
    }
    
    public test() {	// 构造方法,在new对象时调用
        System.out.print("E");
    }
    
    static {
        System.out.print("F");
    }
}
//AFCBED

this

  • this保存当前对象的内存地址,指向自身。
  • this存储在堆内存中对象的内部。
  • this不能使用在静态方法中,可以使用在实例方法和构造方法中,如果是在构造方法中使用,可以通过当前的构造方法去调用另一个本类的构造方法
//构造方法中使用this
public class test {
	private int year;
	private int month;
	
	public test() {
        /* this.year = year;
		this.month = month;*/
		this(2022, 9);	//代码复用,只能在构造方法的第一行
	}
	
	public test(int year, int month) {
		this.year = year;
		this.month = month;
	}
}
  • 一般情况下this可以省略 ,某些情况比如区分局部变量和实例变量时this不能省略
//以下情况this不能省略
public class test {
	private int no;
	
	public test(int no) {
		this.no = no;
	}
	
	public void setNo(int no) {
		this.no = no;
	}
}

extends(继承)

  • 基本作用:代码可以得到复用。
  • 重要作用:有了继承关系,才有了后期的方法覆盖和多态机制。
  • 子类继承父类,除构造方法不能继承外,剩下都可以继承,但是私有的属性无法在子类中直接访问(可以通过间接方法比如set和get)

方法覆盖

子类继承父类之后当继承过来的方法不满足需求,子类可以将该方法重新编写,称为“方法覆盖”。
  • 条件一:两个类必须有继承关系
  • 条件二:方法的返回值类型、方法名、形式参数列表要和被覆盖的方法一模一样
  • 条件三:访问权限不能更低,可以更高(比如不能protected覆盖public)
  • 条件四:重写之后的方法不能比之前的方法抛出更多的异常,可以更少
注意
  • 注意一:私有方法无法覆盖
  • 注意二:方法覆盖只是针对于实例方法,静态方法覆盖没有意义
class Dad {
  public void way() {
    System.out.println("this is dad");
  }
}

class Son extends Dad {
  public void way() {
    System.out.println("this is son");
  }
}

public class test {
  public static void main(String[] args) {
    Son s = new Son();
    s.way();	// this is son
  }
}

多态

  • 父类型的引用指向子类型的对象
  • 多种形态(编译形态和运行形态)
  • 编译阶段:静态绑定父类的方法
  • 运行阶段:动态绑定子类型对象的方法
  • 在开发中的作用:降低程序的耦合度,提高程序扩展力

向上转型和向下转型

前提:两者之间必须有继承关系

向上转型

子 --> 父(自动类型转换)

animal a = new cat();

向下转型(为了调用或者执行子类中特有的方法)

父 --> 子(需要添加强制类型转换符)

cat c = (cat)a;

为了规避ClassCastExceptin风险,进行向下转型之前先用instanceof 运算符进行判断

public class test {
	public void test1(animal a) {
        if(a instanceof cat) {
            cat c = (cat)a;
            c.catchMouse();
        }
        else if(a instanceof bird) {
            bird b = (bird)a;
            b.sing();
        }
    }
}

instanceof 运算符

语法:引用 instanceof 类型

作用:可以在运行的时候动态的判断引用指向的对象的类型

animal a = new cat();
System.out.println(a instanceof animal);	//true
System.out.println(a instanceof cat);	//true
System.out.println(a instanceof bird);	//flase

super

  • super不能使用在静态方法中,可以使用在实例方法和构造方法中

  • 语法:super.super()

    • super.属性名 【访问父类型的属性】
    • super.方法名 【访问父类型的方法】
    • super(实参) 【调用父类型的构造方法】
  • super.大部分情况可以省略,当父类和子类中有同名的属性或者相同方法,要在子类中访问父类的属性或者方法时,super不可省略

    class customer{
        String name;
        
        public customer(){}
        public customer(String name){
            this.name = name;
        }
        
        public void way(){
            System.out.println("父类方法调用了");
        }
    }
    
    class VIP extends customer{
        String name;
        
        public VIP(){}
        public VIP(String name){
            super(name);
        }
        
        public void way(){
            System.out.println("子类方法调用了");
        }
        public void dosome(){
            System.out.println(this.name + "is doing something...");	//null is doing something...
            System.out.println(super.name + "is doing something...");	//zazahui is doing something...
            System.out.println(name + "is doing something...");	//null is doing something...
            this.way();	//子类方法调用了
            super.way();	//父类方法调用了
            way();	//子类方法调用了
        }
    }
    
    public class test{
        public static void main(String[] args){
            VIP v = new VIP("zazahui");
            v.dosome();
        }
    }
    
  • super()只能出现在构造方法的第一行,通过当前的构造方法去调用父类中的构造方法。目的:创建子类对象时,先初始化父类型特征

  • 当构造方法的第一行既没有this()也没有super()时,默认会有一个super()

public class test {
  public static void main(String[] args) {
    new c();
    //1 3 6 5 4
  }
}

class a{
    public a(){
        System.out.println("1: a的无参构造方法")
    }
}

class b extends a{
    public b(){
        System.out.println("2: b的无参构造方法")
    }
    public b(String name){
        //super();
        System.out.println("3: b的有参构造方法(String)")
    }    
}

class c extends b{
    public c(){
        this("Simho");
        System.out.println("4: c的无参构造方法")
    }
    public c(String name){
        this(111, name);
        System.out.println("5: c的有参构造方法(String)")
    }    
    public c(int id, String name){
        super(name);
        System.out.println("6: c的有参构造方法(int, String)");
    }        
}
  • super不是引用,不保存内存地址,也不指向任何对象,只是代表当前对象的父类型特征,所以不能单独使用。

final

  • 最终的,不可变的

  • final修饰的类——无法被继承

  • final修饰的方法——无法被覆盖、重写

  • final修饰的变量

    • final修饰的局部变量——无法进行二次赋值

      public class test {
          public static void main(String[] args) {
              final int k = 100;
              int k = 200; //不允许
          }
      }
      
    • final修饰的"引用"变量——无法二次创建并指向新对象(即内存地址不可改变);对象内部的属性可以改变

      public class test {
          public static void main(String[] args) {
              final A a = new A();
              a = new A(); //不允许
              a = null; //也不允许
          }
      }
      class A {
      	int age;
      }
      
    • final修饰的实例变量——除了无法进行二次赋值,还必须要手动赋初始值,系统不会对其赋默认值

      public class test {
          final int a = 10;
      }
      or
      public class test {
          final int a;
          public test() {
              this.a = 10;
          }
      }
      

      final修饰的实例变量——一般在final前面添加static以节省内存空间,static final联合修饰的变量称为“常量”

      • 常量和静态变量一样,都是存储在方法区,且在类加载时初始化
      • 区别在于常量的值无法改变,一般都是公开的
      public class Chinese {
          String id;
          String name;
          public static final String COUNTRY = "中国";
      }
      

abstract(抽象类)

  • 类和类之间具有共同特征,将这些特征提取出来,形成的类就是抽象类。

  • 由于类不是真实存在的,因此抽象类无法实例化、无法创建对象,所以抽象类是用来被子类继承的,因此finalabstract不能联合使用。

  • 抽象类虽然无法实例化,但是有构造方法,其构造方法是给子类使用的。

  • 抽象类属于引用数据类型。

  • 抽象类的子类可以是抽象类。

  • 抽象类中不一定有抽象方法,但是抽象方法一定要在抽象类中。

  • 若非抽象类继承抽象类,必须要将抽象类中的抽象方法全部实现(重写/覆盖)。

    abstract class Account {
        public abstract void dosome(); //抽象方法 
    }
    
    class CreditAccount extends Account {
        public void dosome(){}
    }
    

    java语言中凡是没有方法体的方法都是抽象方法(错误) //Object类中就有很多没有方法体的方法

interface(接口)

  • 接口属于引用数据类型。

  • 接口支持多继承,一个类可以实现多个接口。

    interface A {}
    interface B {}
    interface C extends A,B {}
    abstract class D implements A,B,C{}
    class E implements A,B,C {}
    
  • 接口是完全抽象的。

  • 接口中所有的元素都是public修饰的。

  • 接口中只有常量+抽象方法(所以接口中不能有方法体);其中常量中的public static final 和 抽象方法中的public abstract可以省略。

    interface Animal {
        String type = "animal";	// 等价于public static final String type = "animal";
        void move();	// 等价于public abstract void move();
    }
    
  • 类与类、接口与接口之间叫做继承,类和接口之间叫做实现。

    继承用extends关键字完成,实现用implements关键字完成。

  • 若非抽象类实现接口,必须将接口中的抽象方法全部实现(重写/覆盖)。

  • extendsimplements同时出现,先extendsimplements

  • 接口可以使用多态。

  • 在开发中的作用:面向接口编程,可以降低程序的耦合度,提高程序的扩展力。

访问控制权限

权限大小:public > protected > default > private

访问控制修饰符 本类 同包 子类 任意位置
public
protected ×
default × ×
private × × ×

异常

  • 编译时异常——必须处理,不然编译报错程序无法运行
  • 运行时异常——可选择处理或者不处理

处理异常的两种方式

  1. 在方法声明的位置上使用throws关键字抛出,谁调用此方法就抛给谁。进行上报处理,后续代码不会执行。
  2. 使用try..catch语句对异常进行捕捉。自行处理消化,语句后续代码仍会执行。
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class exceptionTest {
  public static void main(String[] args) {
    try {
      m1();
      System.out.println("若m1()出现异常,此语句不会执行");
    } catch (FileNotFoundException e) {
      System.out.println("文件路径可能存在错误!");
    }

    System.out.println("异常被处理,此语句可以正常执行");
  }
  public static void m1() throws FileNotFoundException { //异常上抛给main
    System.out.println("m2 begin");
    m2();
    System.out.println("m2 end"); //不会执行
  }
  public static void m2() throws FileNotFoundException { //异常上抛给m1
    System.out.println("m3 begin");
    m3();
    System.out.println("m3 end"); //不会执行
  }
  public static void m3() throws FileNotFoundException { //异常上抛给m2
    new FileInputStream("c://一个不存在的路径");
  }
}
/*
m2 begin
m3 begin
文件路径可能存在错误!
异常被处理,此语句可以正常执行
 */
  • 异常处理机制的作用:增强程序的健壮性(异常发生了也不影响程序的执行)。

  • catch()括号中的类型和throws关键字后的类型,可以填写具体的异常类型,也可以填写该异常类型的父类型。

  • 若异常有多个,可以写多个catch对应不同的异常一个个的处理,但是需要遵循从上到下、从小到大的原则(写了父类型后面就不能跟它的子类型)。

finally子句

  • 可以不加,但必须同try一起使用,finally中的语句最后执行,也一定会执行。

  • 通常在finally语句块中完成资源的释放/关闭。

实现多线程的方式

  • 第一种:编写一个类,直接继承java.lang.Thread,重写run方法

    public class threadTest {
      public static void main(String[] args) {
        myThread t = new myThread();
        t.start();	// 启动一个分支线程,在JVM中开辟一个新的栈空间。启动成功的线程会自动调用run方法
        for(int i=0; i < 1000; i++) {
          System.out.println("主线程-->" + i);
        }
      }
    }
    
    class myThread extends Thread {
      public void run() {
        for(int i=0; i < 1000; i++) {
          System.out.println("分支线程-->" + i);
        }
      }
    }
    
  • 第二种:编写一个类,实现java.lang.Runnable接口,实现run方法

    public class threadTest {
      public static void main(String[] args) {
        myRunnable mr = new myRunnable();
        Thread t = new Thread(mr);
        //或者合并写成 Thread t = new Thread(new myRunnable()); 推荐这种
        t.start();
        for(int i=0; i < 1000; i++) {
          System.out.println("主线程-->" + i);
        }
      }
    }
    
    class myRunnable implements Runnable {
      public void run() {
        for(int i=0; i < 1000; i++) {
          System.out.println("分支线程-->" + i);
        }
      }
    }
    
  • 基于第二种,还可以使用匿名内部类

    public class threadTest {
      public static void main(String[] args) {
        Thread t = new Thread(new Runnable() { // 相当于new [匿名] implements Runnable() {}
            public void run() {
            for(int i=0; i < 1000; i++) {
              System.out.println("分支线程-->" + i);
            }
      }
        }); 
        t.start();
        for(int i=0; i < 1000; i++) {
          System.out.println("主线程-->" + i);
        }
      }
    }
    

数组

  • 数组非基本数据类型,是一种引用数据类型
  • 数组中的元素类型必须统一,例如int类型的数组只能存储int类型,Person类型的数组只能存储Person类型
  • 数组中首个元素的内存地址作为整个数组对象的内存地址,数组中元素的内存地址是连续的
初始化一维数组
public class test {
  public static void main(String[] args) {
    // 静态初始化语法格式
    int[] num = {1, 2, 3, 4};	
    String[] str = {"a", "b", "c"};
      
    Person per1 = new Person();
    Person per2 = new Person();  
    Person[] p = {per1, per2};
    
    // 动态初始化语法格式
    int[] num = new int[4];	
    String[] str = new String [3];
      
    Person[] p = new Person[2];
    P[0] = new Person();
    P[1] = new Person();
  }
}
其他初始化方式
public class test {
  public static void main(String[] args) {
    printArray(new int[]{1,2,3});	// 静态初始化
    // 1 2 3
      
    printArray(new int[3]);	// 动态初始化
    // 0 0 0
  }

  public static void printArray(int[] array) {
    for (int i = 0; i < array.length; i++) { // length是数组的一个默认方法,用于表示数组元素的个数
      System.out.println(array[i]);
    }
  }
}
数组拷贝 / 扩容

System.arraycopy(拷贝源, 源起始位置, 拷贝目标, 目标起始位置, 拷贝长度)

public class test {
  public static void main(String[] args) {
    int[] src = {1, 2, 3, 4};
    int[] dest = new int[10];
    System.arraycopy(src, 0, dest, 3, src.length);

    for (int i = 0; i < dest.length; i++) {
      System.out.println(dest[i]);	// 0 0 0 1 2 3 4 0 0 0
    }
  }
}
初始化二维数组
public class test {
  public static void main(String[] args) {
    int[][] a = {	// 静态初始化
      {1,2,3},
      {4,4,4,5,5},
      {7}
    };

    int[][] b = new int[3][4];	// 动态初始化
  }
}
其他初始化方式和一维同理

IO流

所有的流都位于java.io.*

文件流:
*java.io.FileInputStream		// 字节输入流
*java.io.FileOutputStream	// 字节输出流
java.io.FileReader		// 字符输入流
java.io.FileWriter		// 字符输出流

转换流(将字节流转换成字符流):
java.io.InputStreamReader
java.io.OutputStreamWriter
    
缓冲流://不用自己开数组
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream

// 在java中只要"类名"以Stream结尾都是字节流,以Reader/Writer结尾都是字符流

所有的流都有close方法,用完流需要关闭管道以释放资源。

所有的输出流都有flush方法,最终输出后需要flush刷新以清空管道。

FileInputStream & FileReader(文件读取)

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class test {
  public static void main(String[] args) {
    FileInputStream fis = null;	// 可以读取任意文件
    FileReader fr = null;	// 只能读取普通文本

    try {
      fis = new FileInputStream("E:\\IDEA_greenEditon\\IdeaProjects\\course\\a");
      fr = new FileReader("E:\\IDEA_greenEditon\\IdeaProjects\\course\\a");

      byte[] bytes = new byte[4]; // 以byte数组为单位,一次读取bytes.length长度的字节
      char[] chars = new char[4]; //  以char数组为单位,一次读取chars.length长度的字符

      int readcount = 0;
      int readcount1 = 0;

      while ((readcount = fis.read(bytes)) != -1) {  // fis.read(bytes)返回每次读取字节的长度,为-1则表示读取完毕
        System.out.print(new String(bytes, 0, readcount));  // 输出每次读取长度的字节
      }

      while ((readcount1 = fr.read(chars)) != -1) {  // fis.read(bytes)返回每次读取字符的长度,为-1则表示读取完毕
        System.out.print(new String(chars, 0, readcount1));  // 输出每次读取长度的字符
      }

    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (fis != null) {
        try {
          fis.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (fr != null) {
        try {
          fr.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
}

FileOutputStream & FileWriter(文件写入)

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

public class test {
  public static void main(String[] args) {
    FileOutputStream fos = null;  // 可以写入任意文件
    FileWriter fw = null; // 只能写入普通文本

    try {
//      fos = new FileOutputStream("E:\\IDEA_greenEditon\\IdeaProjects\\course\\a");  // 覆盖写入
      fos = new FileOutputStream("E:\\IDEA_greenEditon\\IdeaProjects\\course\\a", true);  // 追加写入

//      fw = new FileWriter("E:\\IDEA_greenEditon\\IdeaProjects\\course\\a");  // 覆盖写入
      fw = new FileWriter("E:\\IDEA_greenEditon\\IdeaProjects\\course\\a", true);  // 追加写入

      byte[] bytes = {97, 98, 99, 100};
      fos.write(bytes); // 写入abcd

      // 写入字符串时要先转成字节
      String s = "你好";
      byte[] bs = s.getBytes();
      fos.write(bs);


      char[] chars = {'你', '好', '朋', '友'};
      fw.write(chars,1,3);  // 第三个参数表示写入长度,写入"好朋友"
      fw.write("哈哈哈");

      fos.flush();	// 写完后刷新管道,以防后续数据丢失
      fw.flush();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (fos != null) {
        try {
          fos.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (fw != null) {
        try {
          fw.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
}
同时进行文件的读取和写入便可实现复制功能

BufferedReader

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;

public class test {
  public static void main(String[] args) throws Exception{	// 为方便此处将所有异常做上抛处理
    FileReader fr = new FileReader("a");
    // 当一个流的构造方法需要另一个流的时候,被传进来的流叫做节点流,外部负责包装的流叫做包装流/处理流
    //节点流和包装流是相对的,此时FileReader为节点流,BufferedReader为包装流
    BufferedReader br = new BufferedReader(fr);

    //缓冲流只能传入字符流,字节流需要先用转换流转成字符流
    FileInputStream fis = new FileInputStream("a");
    InputStreamReader reader = new InputStreamReader(fis);
    BufferedReader br1 = new BufferedReader(reader);
    // 可以合并成以下形式
//    BufferedReader br1 = new BufferedReader(new InputStreamReader(new FileInputStream("a")));

    String str = null;
    while ((str = br1.readLine()) != null) {
      System.out.println(str);
    }
      
    br.close();
    br1.close();
  }
}

其他几个缓冲流同理,不再赘述

Properties

  • Properties是一个Map集合,继承Hashtable,Properties的keyvalue都是String类型

  • 数据的插入和读取

    Properties pro = new Properties();
    pro.setProperty("k1","v1");
    String value = pro.getProperty("k1");
    
  • 利用IOProperties创建对象

    String key = "b";
    Properties pro = new Properties();
    pro.load(new FileInputStream("a.properties"));	// a.properties文件存放了 b=java.util.String
    
    String className = pro.getProperty(key);
    Class c = Class.forName(className);
    Object o = c.newInstance();
    

序列化与反序列化

  • 参与序列化与反序列化的对象,必须要实现serializable接口
  • serializable接口是一个标志接口,起到标识作用,java虚拟机会根据此接口为该类自动生成一个序列化版本号
  • 序列化版本号可以标识每个类,反序列化的时候便以区分
  • 建议将序列化版本号自行手动写出来
// user类
import java.io.Serializable;

public class user  implements Serializable {
  private int no;
  private String name;
  //transient关键字表示游离的,不参与序列化
  private transient int age;  // age属性不参与序列化

  private static final long serialVersionUID = 1L;  //手动设置序列化版本号

  public user(int no, String name, int age) {
    this.no = no;
    this.name = name;
    this.age = age;
  }

  public int getNo() {
    return no;
  }

  public void setNo(int no) {
    this.no = no;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  //重写tostring方法
  @Override
  public String toString() {
    return "user{" +
      "no=" + no +
      ", name='" + name + '\'' +
      ", age=" + age +
      '}';
  }
}
//序列化操作
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class test {
  public static void main(String[] args) throws Exception{
    user u = new user(111,"admin",18);
    ObjectOutputStream oop = new ObjectOutputStream(new FileOutputStream("users"));
    oop.writeObject(u);

    oop.flush();
    oop.close();
  }
}
// 会在根目录生成users字节码文件
//反序列化操作
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class test1 {
  public static void main(String[] args) throws Exception{
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("users"));
    Object obj = ois.readObject();
    System.out.println(obj);

    ois.close();
  }
}
// user{no=111, name='admin', age=0}

反射

  • 反射:通过反射机制可以操作字节码文件

  • 作用:使程序更加灵活

  • 反射机制相关的重要的类

    java.lang.class
    java.lang.reflect.Field		//重点
    java.lang.reflect.Method	//重重点
    java.lang.reflect.Constructor 
    
  • 获取java.lang.class实例

    // 第一种:Class c = Class.forName("完整包名+类名")
    Class c1 = null;
    c1 = Class.forName("java.lang.String");	// c1代表String.class文件,或者说c1代表String类型
    
    // 第二种:Class c = 对象.getClass()
    String s = "aaa";
    Class c2 = s.getClass();
    
    // 第三种:Class c = 类型.class
    Class c3 = String.class;
    Class d = int.class;	// d代表int类型
    
    System.out.println(c1 == c2);	// true(==判断的是对象的内存地址)
    System.out.println(c1 == c3);	// true
    
  • 获取class后,可以调用无参构造方法来实例化对象

    c = Class.forName("test.user");
    Object o = c.newInstance();
    //newInstance方法调用的是该类的无参构造方法
    //如果没有无参构造方法会出现“实例化”异常
    
    Class.forName("test.user");
    //如果单独使用Class.forName会进行类的加载,类加载时执行静态代码块
    
  • Field

    public class test1 {
      public static void main(String[] args) throws Exception{
        Class c1 = null;
        c1 = Class.forName("test1.user");	// c1代表String.class文件,或者说c1代表String类型
        Object o1 = c1.newInstance(); // 获取对象
    
    // Filed:
        Field f1 = c1.getDeclaredField("no"); //获取单个属性
        f1.setAccessible(true); // 打破封装,使其可以访问private属性
    
        // get和set:
        f1.set(o1,111); // 为o1对象的f1属性赋值
        System.out.println(f1.get(o1)); // 访问o1对象的f1属性
    
        Field[] fields = c1.getDeclaredFields(); // 获取所有属性,数组的每个元素存储属性对象
        for(Field field : fields) {
          // 获取属性修饰符列表:
          int i = field.getModifiers(); // 属性修饰符以int类型返回
          String fieldModifier = Modifier.toString(i); // 将int类型转为对应修饰符字符串
    
          // 获取属性类型:
    //    Class type = field.getType();  // 返回值为class类型
    //    String fieldType = fieldType.getName(); //.getSimpleName()
          String fieldType = field.getType().getSimpleName();  // 以上两条可以合并成一句;也有.getSimpleName()
    
          // 获取属性名:
          String fieldName = field.getName();
    
          System.out.println(fieldModifier + " " + fieldType + " " +fieldName);
        }
      }
    }
    
  • Method

    public class test1 {
      public static void main(String[] args) throws Exception{
        Class c1 = null;
        c1 = Class.forName("test1.user");	// c1代表String.class文件,或者说c1代表String类型
        Object o1 = c1.newInstance(); // 获取对象
          
    //Method:
        Method[] methods = c1.getDeclaredMethods();
    
        for(Method method : methods) {
          StringBuilder s = new StringBuilder();
    
          // 获取方法修饰符列表:
          String methondModifier = Modifier.toString(method.getModifiers());
    
          // 获取方法类型:
          String methodType = method.getReturnType().getSimpleName();
    
          // 获取方法名:
          String methodName = method.getName();
    
          s.append(methondModifier+" "+methodType+" "+methodName+" (");
    
          // 获取方法参数列表
          Class[] parameters = method.getParameterTypes();
          for(Class parameter : parameters) {
            String methodParameter = parameter.getSimpleName();
            s.append(methodParameter+",");
          }
          if (parameters.length > 0) {
            s.deleteCharAt(s.length()-1); // 删除最后一个字符
          }
          s.append(")");
    //      System.out.println(s);
        }
    
        Method m1 = c1.getDeclaredMethod("login", String.class, int.class); // 获取c1类的参数列表为String、int的b方法
        Object retValue = m1.invoke(o1, "admin", 123456);  // o1对象调用该方法
      }
    }
    
  • Constructor(说一下调用无参和有参构造方法,其他的和Method相似)

    Constructor con1 = c1.getDeclaredConstructor();
    Object ob1 = con1.newInstance(); // 同c1.newInstance()一样,后者在jdk9之后的版本不再建议使用
    
    Constructor con2 = c1.getDeclaredConstructor(int.class, String.class, int.class);
    Object ob2 = con2.newInstance(1, "admin", 18);
    
  • 获取父类和父接口

    // 获取父类
    Class superClass = c1.getSuperclass();
    String scName = superClass.getName();
    System.out.println(scName);
    
    // 获取父接口
    Class[] interfaces = c1.getInterfaces();
    for(Class in : interfaces) {
    	System.out.println(in.getName());
    }
    

可变长度参数

  • 语法:类型...
  • 可变长参数的个数为0~N个
  • 可变长度参数必须在参数列表的最后一个位置上,并且只能有一个可变长参数
  • 可变长参数可看作是一个数组
public class test {
  public static void main(String[] args) {
    m(1);
    System.out.println("===========");
    m(2,"aa");
    System.out.println("===========");
    m(3,"bb","cc");
  }

  public static void m(int a, String... str) {
    for (int i = 0; i < str.length; i++) {
      System.out.println(str[i]);
    }
  }
}
/*
===========
aa
===========
bb
cc
 */

通用径获取方式:

  • 前提:文件必须在类路径下,也就是src路径下(src是类的根路径)
// 假如src的test文件夹下有个a.txt文件
String path = Thread.currentThread().getContextClassLoader().getResource("test/a.txt").getPath();
System.out.println(path);
// /E:/IDEA_greenEditon/IdeaProjects/course/out/production/course/test/a.txt

// 直接以流的形式返回
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("test/a.txt");

注解(Annotation)

  • 自定义注解的语法格式

    [修饰符列表] @interface 注解类型名 {
    }
    
    // myAnnotation.java
    public @interface myAnnotation {
      int age();
      String[] name();
    }
    
    // test.java
    public class test {
      @myAnnotation(age = 18, name = {"admin", "root"}) // 当数组只有一个元素时,花括号可以省略
      public static void main(String[] args) {
      }
    }
    
  • JDK内置的常用注解

    Deprecated:用来表明这个注解标注的元素已过时
    
    Override:用来检查是否重写了父类的方法;该注解只能出现在方法上
    
  • 元注解:用来标注注解类型的"注解"

    • 常用的元注解

      Target:用来标注"被标注的注解"可以出现在哪些位置上
      	例如:@Target(ElementType.METHOD) 表名该注解只能出现在方法上
              
      Retention:用来标注"被标注的注解"最终保存在哪里
          @Retention(RetentionPolicy.SOURCE):表示该注解只能保存在java源文件中
          @Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中
          @Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且能被反射机制所读取
      
  • 当注解中仅有一个名为value的属性时,指定属性值时可以忽略该属性名,比如上面的两个元注解

标签:String,int,class,System,笔记,public,new,javaSE,节点
From: https://www.cnblogs.com/s1mh0/p/17064760.html

相关文章

  • JavaScript学习笔记—复制
    9.复制(1)浅拷贝(shallowcopy)通常对对象的拷贝都是浅拷贝只对对象的浅层进行复制(只复制一层)如果对象中存储的数据是原始值,那么拷贝的深浅是不重要浅拷贝只会对对象本......
  • 学习笔记——SSM整合(思路、步骤)
    2023-01-22一、SSM整合1、Spring+SpringMVC(1)容器管理对象,由DispatcherServlet管理(2)Spring容器对象,由ContextLoaderListener管理2、解决组件扫描的冲突问题(1)SpringM......
  • JavaScript学习笔记—数组的方法
    1.非破坏性方法(1)Array.isArray():用来检查一个对象是否是数组console.log(Array.isArray([1,2,3,4]));//trueconsole.log(Array.isArray({name:"孙悟空"}));//fals......
  • 刷刷刷 Day 16 | 222. 完全二叉树的节点个数
    222.完全二叉树的节点个数LeetCode题目要求给你一棵完全二叉树的根节点root,求出该树的节点个数。完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外......
  • 编译snowboy 笔记
    1.安装依赖sudoapt-getinstallpulseaudiosoxpython3-pyaudioswiglibatlas-base-devpython3-dev2.获取源代码gitclonehttps://github.com/Kitt-AI/snowboy.git......
  • 《RPC实战与核心原理》学习笔记Day5
    06|RPC实战:剖析gRPC源码,动手实现一个完整的RPC我们通过动态代理技术,屏蔽RPC调用的细节,从而让使用者能够面向接口编程。什么是gRPC?gRPC是由Google开发并且开源的一款......
  • 节点流和处理流
    节点流和处理流的区别和联系节点流是底层流/低级流,直接跟数据源相接。处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出......
  • AC 自动机学习笔记
    前置知识:KMP,trie。一.自动机这里的自动机都指有限状态自动机(DFA)。一个DFA可以理解为一张有向图,由有限的状态(点),字母表,转移函数(边),开始状态与终止状态(起点,终点)组成。AC......
  • 学习笔记——SpringMVC拦截器的两种装配方式;SpringMVC拦截器工作原理;SpringMVC中的异
    2023-01-22 一、SpringMVC拦截器的两种装配方式1、全局装配(放置在springmvc.xml中)<!--装配拦截器--><!--全局装配--><mvc:interceptors><ref......
  • 数据结构笔记(一)
    程序=数据结构+算法数据结构(C语言版)(第2版)https://weread.qq.com/web/reader/b57320b071db572cb578fb5数据结构与算法基础(青岛大学-王卓)https://www.bilibili.com/video......