javase基础知识笔记

24 篇文章 0 订阅

javase基础知识笔记

1.jdk下载与环境变量配置
  • 下载官网:(https://www.oracle.com/index.html)
  • 配置:变量名为JAVA_HOME, 变量值为安装路径如:E:\javahome, path值:%JAVA_HOME%bin
  • win+R, 输入cmd, 回车,再输入javac -version回车查看版本,再输入 java -version 若都成功则配置安装成功。
2.基本数据类型(四型八种)
  • byte by = 123;//一个字节,八位
  • short sh = 456;//短整型,两个字节,16位
  • int i = 12332;//整型, 四个字节,32位
  • long lon = 23142342131L;//长整型,八个字节,64位
  • float fo = 175.9F;//单精度浮点型,四个字节,32位,
  • 声明一个float类型变量,一个普通的小数默认是double类型
    必须在常数的后面加上f或F
  • double dou = 123.87;//双精度浮点型,八个字节,64位
  • boolean passed = false;//boolean类型,jvm中规定,计算机底层使用int类型存储Boolean类型,所以4字节
  • //字符类型变量char,可以和int整型数据类型相互转换但是不能超过最大值,\表示转义字符
    char ch1 = ‘男’; int a = 66; System.out.println(“ch1对应的整型是:” + (int)ch1);//强制类型转换 System.out.println("a对应的字符型是:" + (char)a);//强制类型转换
  • /强制类型转换,从高精度向低精度转换/(需要的低数据类型)高精度数据类型例如:float f = (float)1212.121d;
3.短路与和短路或
  • boolean bool = n1 > n2 && ++n1 > n3, 如果n1>n2为flase,则后面部分则不会被执行,称为短路与。
  • boolean bool2 = n1 > n2 || --n1 >n3, 如果n1>n2为真,则后面不会被执行,称为短路或。
  • 按位与&和按位或|:6661. 按位与和逻辑与相似,但不会出现短路现象,按位或亦是如此。
  • 按位非~类似!
4.移位运算符
  • 左移位,表示3向左移位2位, 左移位运算<< 左移一位相当于乘2,左移两位相当于乘2的2次方。

    3 <<2(3为int型)

    1)把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,

    2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,

    3)在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,转换为十进制是12。

  • 向左移动32位,结果和输入的数一样 * 原因:32%320,移动0位 * 如果向左移动33位,33%321,移动1位 结果:输入24,得到24 * 2^1 =48

  • 右移位运算>>,右移一位相当于除2,右移n位相当于除2的n次方。无符号向右侧移动>>>,对负数有效变为正数,对整数和>>一样

5.循环
  • while循环:当条件为true时,可使用break;关键字跳出循环。continue;关键字表示结束本次循环,继续下一次循环。

     /*
      * 计算出100以内所有偶数的和,偶数的和,并比较大小,输出
      */
            int a = 1;
            int odd_number_sum = 0;//奇数和
            int even_number_sum = 0;//偶数和
            while (a < 101) {
                if (a % 2 == 0) {//判断为偶数
                    even_number_sum += a;
                } else {
                    odd_number_sum += a;
                }
                a++;
            }
    
  • do while循环:至少执行一次

      /*生成随机数,用户输入0~5的数,猜数字游戏,do while循环至少执行一次 */
            Scanner scanner = new Scanner(System.in);
            //生成一个随机数
            Random random = new Random();//new一个生成随机数的对象
            int randomNumber;
            int number;
            do {
                System.out.println("请输入一个范围在0~5的整数:");
                number = scanner.nextInt();
                randomNumber = random.nextInt(5);//随机生成一个小于5的整数
                if (number == randomNumber) {
                    System.out.println("恭喜你猜对了,随机数是" + randomNumber);
                } else {
                    System.out.println("对不起,你猜错了,随机数是" + randomNumber);
                }
            } while (randomNumber != number);
    
  • for循环:

     //打印九九乘法表
    for (int i = 1; i <= 9; i++) {//外层循环控制换行
       for (int j = 1; j <= i; j++) {//内层循环输出
          System.out.print(j+ " x " + i + " = " + (i * j) + "   ");
          }
            System.out.println();//换行
       }
    
  • for循环迭代:

    //for循环迭代
       int[] nums = {12, 34, 567, 34, 1324, 12};//数组
            for (int i : nums) {
                System.out.print(i + "  ");
            }
    
6.冒泡排序

1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

3、针对所有的元素重复以上的步骤,除了最后一个。

4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

//冒泡排序
        int temp;//临时变量
        for (int i = 0; i < scores.length - 1; i++) {//外层循环控制总的排序次数
            /*内层循环实现排序*/
    for (int j = 0; j < scores.length - 1 - i; j++) {
                /*对相邻两个数进行判断*/
          if (scores[j] < scores[j + 1]) {
                temp = scores[j];
                scores[j] = scores[j + 1];
                scores[j + 1] = temp;//依次比较将最小数置于末尾
                }
            }
        }
        /*使用冒泡排序递增排序*/
for (int i = 0; i < scores.length - 1; i++) {
    for (int j = 0; j < scores.length - 1 - i; j++) {
                if (scores[j + 1] < scores[j]) {
                    temp = scores[j + 1];
                    scores[j + 1] = scores[j];
                    scores[j] = temp;
                }
            }
        }
7.数组
  • 一维数组:String[] names = {"小米", "小明", "莱昂纳多"};静态方式创建数组 ,数组在JVM中采用栈和堆的储存方式,通过names在栈中地址访问堆(里面为数据) int[] nums = new int[5];//指定数组长度

    int[] nums = {56, 28, 15, 999, 30, 65, 12, 77};
            int temp;//临时变量
            for (int i = 0; i < nums.length / 2; i++) {
                temp = nums[i];
                nums[i] = nums[nums.length - (i + 1)];
                nums[nums.length - (i + 1)] = temp;
            }
            for (int num : nums) {
                System.out.print(num + "\t");
            }
    
  • 二维数组:int[][] stuScores;//声明二维数组变量

    `  stuScores = new int[3][3];//创建一个二维数组`
    
8.面向对象
  • java对象在JVM中储存:Person person;//声明一个自定义类型的局部变量,存储在JVM的栈中, 使用构造方法创建一个Person类型的对象;赋值给person变量, 对象存储在JVM的堆中;只有new才会在内存堆中新建一个对象 person = new Person();

  • 访问修饰符:

    1. public:公共的,最大访问级别。
    2. protected:保护的,不同包中只有子类允许访问。
    3. 缺省:默认的,不同包中不允许访问。
    4. private:私有的,只允许在本类中访问。
  • 构造方法:

    1. 方法名称和类名完全相同,没有任何返回类型,这样的方法是构造方法(构造器)

    2. 构造方法是用来创建对象使用的,使用new 运算符调用并创建一个对象

    3. 带参数的构造器目的就是为对象进行成员属性初始化

       /*局部变量和成员实例属性重合时可以使用this关键字指向成员变量*/
          public Employee(String name, int workAge) {
          this.name = name;
          this.workAge = workAge;
          System.out.println(name + " " + workAge);
          }
      
    4. 如果构造器被定义多个称为构造方法重载构造器重载,自定义有参构造器将会覆盖系统默认提供的无参构造器,如果需要使用则必须重新显示定义。

9.继承,多态,接口
  • 继承:继承是类与类之间的关系,非对象与对象之间的关系,使用关键字extend, 创建子类对象时总是要先创建一个父类对象,默认子类的构造方法总是自动调用父类的无参构造方法 .
  • java的三大特性:封装、继承、多态(方法重载、方法重写)。
  • final关键字修饰的类不能被继承,构造方法不能被继承,final修饰的类不能被继承,不能被重写。
  • 方法重载是在同一个类中,方法重写出现在子类当中
  • super关键字,不能出现在静态方法中,super关键字在子类的构造方法中代表父类的构造器。
  • 抽象类:
    1. Java核心编程思想是面向对象,面向对象核心编程思想是面向抽象。
    2. 不能使用final关键字修饰。
    3. 自身不能够实例化。
    4. 用来被继承。
  • 适配器: 适配器(Adaptor)创建一个普通类作为适配器类,继承抽象类,实现所有抽象类方法,在用非抽象子类继承适配器,选择性重写抽象方法。
  • 接口:接口中属性定义必须是公共的,静态的常量;接口中只允许定义公共的抽象的实例方法。接口中所有对象都是上转型对象。
10.静态代码块
  • 允许访问静态属性,调用静态方法,定义局部变量及常量,定义局部类。

  • 不允许访问实例属性和方法以及定义方法。

  • 静态代码块属于类,和对象无关,随类的加载而加载。

/*定义静态的常量*/
   private static final String DRIVER;
   private static final String URL;
   private static final String USER;
   private static final String PASSWORD;
/*静态块
     * 可以访问静态常量,静态变量,静态方法
     * 定义静态内部类
     * */
    static {
        //给常量赋值
        DRIVER = "com.mysql.jdbc.Driver";
        URL = "jdbc:mysql://localhost:3306/java";
        USER = "root";
        PASSWORD = "123456";
    }
11.常用库介绍
  • Object类:

    1. 是所有类的超级父类,java任何引用类型对象都可以赋值给Object类型变量。
    2. Object类提供的常用方法:toString()方法;equals方法用来判定给定对象是否与当前对象相等;getClass方法返回当前对象的运行时类(Class)对象,此方法不允许子类进行重写:public final Class getClass();
  • Character包装类:

    1. Character.isDigit(chars[i])判断是否为数字
    2. Character.isLetter(chars[i])判断是否为字母
    3. Character.isLowerCase(chars[i])判断是否为小写字母
    4. Character.isUpperCase(chars[i])判断是否为大写字母
    5. Character.toUpperCase(chars[i]);字母转换为大写字母
    6. Character.toLowerCase(chars[i]);字母转换为小写字母
  • Integer:

    String strNumber = Integer.toString(number);//将整型转换为字符串
    
    Integer.parseInt(String.valueOf(chars[i]));//将字符转换为字符串再转换整型
    
12.String字符串以及常用方法
  • String str=“IU”;字符串常量不可以被更改只能被覆盖;存储在jvm堆中的静态常量区.

  • toCharArray();此方法返回char型数组.

  • contains(" ")判断是否包含空格

  • length();返回字符串长度

  • String str3 = new String(chars, 3, 8);//aChinese,3:表示索引,8:索引开始取几个

  • 比较两个字符串是否相等,equals比较的是字符串的序列化值是否相等,==比较值和是否是同一个对象

  • 通过索引查找字符:charAt(index);

  • 判断结尾和开始:startsWith("我爱中国"),endsWith("qq.com");

  • 去掉字符串前后的空格:str.trim();

  • 查找字符串中指定字符索引:

    1. email.indexOf('@')返回字符索引值
    2. email.indexOf(".com")返回字符串索引
    3. email.indexOf('9',0)从指定索引查找
  • str.split(tag);//返回一个字符串数组

  • 提取字串:

    1. substring(3);从索引位置开始提取
    2. substring(3, 12);//3:开索引始,12:索引结束(最后不取该值)
  • toLowerCase();转换为小写

  • toUpperCase();转换为大写

  • replace("小", "大");//将小替换为大

  • StringBuffer:StringBuffer buffer = new StringBuffer("^_^ ")

    1. StringBuffer是线上安全,线程同步的
    2. buffer.append("qwq")连接字符串
  • StringBuilder:StringBuilder stringBuilder = new StringBuilder(base);//构建可变字符串

    1. stringBuilder.toString();//返回连接的字符串
    2. 非线程同步,不涉及多线程使用比StringBuffer效率更高
13.日期和时间类
  1. SimpleDateFormat实现对Date的字符串格式化,是DateFormat的子类
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String birthday = sdf.format(this.birthday);//对日期对象进行格式化

Calendar对象的创建和使用(抽象类,不能实例化对象)日历

Calendar cal = Calendar.getInstance();//使用默认时区并指向当前系统时间创建一个日历实例

 /*获取年月日*/
      int year = cal.get(Calendar.YEAR);
      int month = cal.get(Calendar.MONTH) + 1;//月份从0开始到11,所以要加1
      int date = cal.get(Calendar.DATE);

Date currentDate = cal.getTime();获取当前日历对象所对应的date对象

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String strCurrentDate = sdf.format(currentDate);

set(int year,int month, int date);设置日历的年份,月份,日期值

14.Math类
  • 所有属性和方法都为static的,不需要创建实例,final修饰的终极类不能被继承
  • Math.abs(-12)计算绝对值
  • Math.cbrt(27.0)计算立方根
  • Math.max(a,b),Math.min(a,b)比较大小
  • Math.pow(x,y)计算x的y次方
  • Math.random()返回0.0到1.0的随机数
15.集合
  1. Map接口(HashMap不是现程安全的。HashTable是线程同步的)
Map<String, Object> carMap = new HashMap<>(); /*存储键值对在哈希表*/        carMap.put("key0", car0);        
carMap.put("key2", car2);        
carMap.put("key3", car3);

carMap.get("key0")通过键取值

/*获取所有键的集合*/ Set keySet = carMap.keySet();不重复

/*取出哈希表中所有的值的集合*/ Collection coll = carMap.values();

carMap.containsKey("key0")判断是否包含给定键

  1. List集合

  2. List<User> userList = new ArrayList<>();//创建List集合对象

  3. userList.contains(new User())//判断集合中是否包含给定对象

  4. userList.clear();清空集合元素

  5. :list中根据索引将元素数值改变(替换)注意 .set(index, element); 和 .add(index, element)

  6. Vector集合实现类:向量集合,适用场景在处理多线程应用中

Vector<User> vector = new Vector<>();//创建集合向量

"当前集合是否为空:" + vector.isEmpty()

当前集合元素个数:" + vector.size())

vector.remove(user3);//删除元素

/*获取Vector独有的新方法提供元素枚举迭代器*/       
Enumeration enu = vector.elements();       
while (enu.hasMoreElements()) {          
    User user = (User) enu.nextElement();//将Object类型强制转换            			System.out.println(user);       
}
  1. Set接口:没有索引,不能存储重复数据,会覆盖。(对象不能一样)

  2. Set<Product> set = new HashSet<Product>(16);//指定初始容量,默认是16,会自动扩容

  3. TreeSet类接口,排序,效率比HashSet要低

  4. TreeSet类接口,排序

16.异常
  • Throwable是所有异常的父类,Error错误重启java虚拟机才行,Exception异常修改代码可解决。
  • 使用throws关键字声明异常,多个异常逗号隔开;使用throw关键字满足条件时抛出异常
try {//捕获异常 
    
	} catch (SQLException | IOException e) {//处理异常           
   String errorMessage = e.getMessage();//获取异常信息
    System.err.println(errorMessage);
    System.out.println(e.getClass().getName());         
    e.printStackTrace();        
} finally {//强制执行块,用于释放被占用的资源           
    try { if (conn != null) {  
        conn.close();               
     }
        } catch (SQLException e) { 
        e.printStackTrace();       
    }
17.File

常用构造方法:

  1. File(File dir,String child)
  2. File(String pathName)
  3. File(String parent,String child)
File resFile = new File("f:\\file\\java.data")
/*判断file对象是否在硬盘上存在*/
      /*createNewFile方法必须确保被创建的文件的父目录都存在,否则出现IOException
       * 系统找不到指定的路径。
       * */
        if (resFile.exists()) {
            System.out.println("文件是可读的吗?" + resFile.canRead());
            System.out.println("文件是可写入的嘛?" + resFile.canWrite());

            System.out.println("文件绝对路径:" + 
            resFile.getAbsolutePath());//f:\file\java.data
            System.out.println("基本路径:" + resFile.getPath());//f:\file\java.data
            System.out.println("父路径:" + resFile.getParent());//f:\file
            System.out.println("文件名称:" + resFile.getName());//java.data
            /*判断文件是目录还是具体文件*/
            System.out.println("文件是目录嘛?" + resFile.isDirectory());//false
            System.out.println("具体文件:" + resFile.isFile());//true
//            System.out.println(resFile.delete());//删除文件
18.输入流(InputStream对目标文件进行读取操作)
  • 读取二进制文件,字节输入流:

     /*建立目标要读取的文件对象*/
            File file = new File(filePath);
            /*基于目标文件建立输入流*/
            InputStream in = null;
            if (file.exists()) {//如果文件存在,创建文件输入流
                try {
                    in = new FileInputStream(file);//使用子类FileInputStream创建二进制输入流
                    int count = 0;//读取到的字节数
                    byte[] bytes = new byte[124];//临时存储读取到的二进制文件
                    /*将读取到的字节数存储到bytes字节中,每次从索引开始存储,存储的长度是	
                     bytes.length,覆盖*/
                    while ((count = in.read(bytes, 0, bytes.length)) != -1) {//循环处理读取,读到文件末尾count为-1
                        String s = new String(bytes, 0, count);//索引0开始,读取长度count
                        System.out.println(s);
                    }
    
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (in != null) {
                            in.close();//关闭流,释放资源
                            System.out.println("关闭成功");
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        
    
  • 字符输入流:读取文本文件不会出现乱码

    FileReader fileReader = null;
            if (file.exists()) {
                try {
                    fileReader = new FileReader(file);
                    int count = 0;
                    char[] chars = new char[30];
                    while ((count = fileReader.read(chars, 0, chars.length)) != -1) {
                        String s = new String(chars, 0, count);
                        System.out.print(s);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        if (fileReader != null) {
                            fileReader.close();//关闭流,释放资源
                            System.out.println("关闭成功");
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
  • 使用BufferedReader缓冲流:提高效率(字符输入流)

    FileReader fileReader = null;//基于文件的普通输入流
         BufferedReader br = null;//基于某个Reader建立的字符缓冲流(处理流)
         if (file.exists()) {
             try {
                 fileReader = new FileReader(file);//基于文件建立普通文本输入流
                 br = new BufferedReader(fileReader);//基于某个Reader建立文本缓冲流
                 int count = 0;
                 char[] chars = new char[25];
                 while ((count = br.read(chars, 0, chars.length)) != -1) {
                     String s = new String(chars, 0, count);
                     System.out.print(s);
                 }
             } catch (IOException e) {
                 e.printStackTrace();
             } finally {
                 try {
                     br.close();
                     fileReader.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
    
             }
         }
    
19.输出流(OutputStream对目标文件进行写入操作)
  • 二进制输出流

        public static void binaryOutputStream(File file) {
            String str = "start=D:\\java课程\\第十九天\\unit12 二级制输出流一(153).mp4";
            byte[] bytes = str.getBytes();//将字符串转换为字节数组
            OutputStream out = null;
            try {
                out = new FileOutputStream(file);
                out.write(bytes);//调用write方法将字节数组的数据写入目标文件file
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
  • 数据比较大时使用缓冲流:

    public static void useBufferedOutputStream(File file) {
           OutputStream os = null;
           BufferedOutputStream bs = null;
           String str = "君不见高堂明镜悲白发,朝如青丝暮成雪。";
           byte[] bys = str.getBytes();
           if (file.exists()) {
               try {
                   System.out.println(file.getAbsolutePath());
                   os = new FileOutputStream(file.getAbsolutePath() + "/诗词.doc");
                   bs = new BufferedOutputStream(os);//基于某个OutputStream建立缓冲输出流
                   bs.write(bys, 0, bys.length);//写入目标文件
               } catch (IOException e) {
                   e.printStackTrace();
               } finally {
                   try {
                       bs.close();
                       os.close();
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
      
               }
           }
       }
    
20.文件的复制(流的对接)
public static void copeFile(File target, File dir) {
        InputStream in = null;//文件输入流,读取文件
        OutputStream os = null;//文件输出流,写入文件
        File copyFile = null;
        if (target.exists()) {//判断目标文件是否存在
            if (!dir.exists()) {//如果目录不存在,创建目录
                dir.mkdirs();
            }
            try {
                in = new FileInputStream(target);//基于文件建立输入流
                String fileName = target.getName();//获取目标文件名称
                /*避免文件重名被覆盖,可以拍使用系统时间的毫秒作为文件前缀*/
                copyFile = new File(dir + "/" + new Date().getTime() + fileName);
                os = new FileOutputStream(copyFile, Boolean.parseBoolean("utf-8"));//基于目标文件建立输出流
                byte[] bytes = new byte[1024];//临时存储字节数据缓冲区
                int count = 0;//记录读取内容的长度
                while ((count = in.read(bytes, 0, bytes.length)) != -1) {
                    //文件复制读取中......
                    System.out.println("文件复制读取中......");
                    os.write(bytes, 0, count);//将临时缓冲区的内容写入目标文件
                }
                System.out.println("文件复制完成");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    os.close();
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
21.序列化读写
  • 序列化流,将一个java对象保存到目标文件(ObjectOutputStream)

    public static void javaSerializableAction(Employee emp, File file) {
           OutputStream os = null;
           ObjectOutputStream oos = null;//序列化流
           if (emp != null) {
               try {
                   os = new FileOutputStream(file);
                   oos = new ObjectOutputStream(os);
                   oos.writeObject(emp);//将序列化文件保存到目标文件
               } catch (IOException e) {
                   e.printStackTrace();
               } finally {
                   try {
                       oos.close();
                       os.close();
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
               }
           }
       }
    
  • 反序列化流,从目标文件读取序列化java对象到内存(ObjectInputStream)

    public static Employee deserializableJavaObject(File file) {
            InputStream in = null;//创建输入流
            ObjectInputStream ois = null;
            Employee emp = null;
            if (file.exists()) {//如果文件存在
                try {
                    in = new FileInputStream(file);
                    ois = new ObjectInputStream(in);
                    //进行反序列化(串行化)
                    Object object = ois.readObject();
                    emp = object != null ? (Employee) object : null;
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
            return emp;
        }
    
22.多线程
  • Thread线程类

    1. 任何一个Thread实例调用start方法将启动运行一个线程
    2. Thread的run方法是线程启动后自动执行的业务方法
  • 线程的生命周期

    1. 第一阶段:新建状态(此时线程还没有运行)
    2. 第二阶段:运行状态(线程开始运行并自动执行run方法)
    3. 第三阶段:中断状态(多种原因使线程处于终止)
    4. 第四阶段:死亡状态(释放线程对象,不在回复运行)
  • Runnable线程接口:有利于实现多个线程之间的数据共享,多个Thread实例共享此接口的run方法

  • interrupt()方法:中断某个线程的状态

  • 线程之间的通信

    1. 同步代码块:被同步的代码块在一个线程对象进行访问时,其他线程是没有访问权限的,只有这个当前线程对象完全执行完了这个代码块,释放了同步锁,其它线程才可以访问这个代码块。

      public class Syncode implements Runnable {
          @Override
          public void run() {
              synchronized (this) {//那个类调用就是那个对象,com.znzz.multiThread.SynCode@8e6ae55
                  Thread current = Thread.currentThread();//获取当前线程
                  for (int i = 0; i < 5; i++) {
                      System.out.println("当前执行同步代码块的线程名称是:" +       current.getName());
                      try {
                          Thread.sleep(1000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
      
    2. 对象同步锁:

      public class SynObject implements Runnable {
          private Dog dog;
      
          public SynObject() {
              if (dog == null) {
                  dog = new Dog();
              }
          }
      
          @Override
          public void run() {
              synchronized (dog) {//对象同步锁
                  Thread current = Thread.currentThread();//获取当前线程
                  for (int i = 0; i < 5; i++) {
                      System.out.println(current.getName() + "正在修改dog名字:");
                      dog.setName("米卡" + i);
                      System.out.println("名字被修改为" + dog.getName());
                      try {
                          Thread.sleep(1000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
      
    3. 方法同步锁:

      public class SynMethod implements Runnable {
          private double money = 100000;
      
          @Override
          public void run() {
              doMoney();
          }
          private synchronized void doMoney() {
              Thread current = Thread.currentThread();
              for (int i = 1; i <= 5; i++) {
                  if (current.getName().equals("会计")) {
                      System.out.println(current.getName() + " 正在入账......");
                      money *= i;
                      System.out.println("账户:" + money);
                  }
                  if (current.getName().equals("出纳")) {
                      System.out.println(current.getName() + " 正在分账......");
                      money = money * i - 0.2 * money;
                      System.out.println("账户:" + money);
                  }
      
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              System.out.println("总帐:" + money);
          }
      }
      
23.网络编程
  • **IP地址:**IP 地址(Internet Protocol Address)是互联网协议特有的一种地址,它是 IP 协议提供的一种统一的地址格式。IP 地址为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。与域名绑定。
  • **端口号:**ip地址是用来标志服务器的。但是一个服务器上会有很多个程序同时使用网络,那怎么保证他们的网络包不串线?好了,端口号就入场了,它是0-65535之间的一个数字。服务端是监听一个固定的端口,比如80,这样客户端在连接的时候都知道该连哪个应用。客户端是从未占用的里面随机挑选一个就可以(但一般不会选1024以下)。
24.枚举数据类型
  1. 枚举类用关键字enum修饰,用来定义不变的值,类似于final修饰的 常量;
  2. 枚举类中还可以定义方法,内部类,变量等,但都必须定义在枚举数据之后。
/*
枚举类型
* */
public enum SignalLamp {//交通信号灯
    RED,
    GREEN,
    YELLOW;
    /*后面定义其他类型及方法*/
    private int num = 100;
    static class InnerClass {

    }
    /*还可以定义接口*/
    interface Dao {

    }
}
25.反射编程
  • Java中的反射编程是通过JVM运行时获取某个类型的字节码(Class)对象,从而利用其反向获取此类型定义的内部信息实现编程的一种机制。

  • Class类:Class类的实例表示正在运行的Java应用程序中的类和接口,是字节码实例。

  • eg.

        public static void main(String[] args) {
            try {
                Class<?> stuClass = Class.forName("com.znzz.practice.Student");
                /*使用字节码对象获取关于这个类的对象实例*/
                Student student = (Student) stuClass.newInstance();//默认调用此类的无参构造实例化对象,返回对象是Object类型
                System.out.println(stuClass.getName());//com.znzz.practice.Student
    
                /*获取类的访问级别*/
                System.out.println(stuClass.getModifiers() == Modifier.PUBLIC);//true
    
                /*获取所有公共级别的字段*/
                Field[] fields = stuClass.getFields();
                for (Field f : fields) {
                    System.out.println(f);//public java.lang.String com.znzz.practice.Student.name
                }
    
                System.out.println("所有访问级别的字段数组长度:" + stuClass.getDeclaredFields().length);//3
    
                /*获取类中定义的构造器*/
                Constructor con0 = stuClass.getConstructor(String.class, Integer.class);
                System.out.println(con0 != null);//true
    
                /*获取所有构造器*/
                Constructor[] constructors = stuClass.getConstructors();
                System.out.println(constructors.length);//3个构造器
    
                /*获取类中定义的方法*/
                Method[] methods = stuClass.getMethods();//获取所有公共访问级别的方法,获取所有方法用stuClass.getDeclaredMethods()
                System.out.println(methods.length);//11包括父类中的方法
                for (Method m : methods) {
                    System.out.println(m.getName());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
  • Constructor类:表示某个类的构造方法实例类型

     public static void main(String[] args) {
            try {
                Class<?> stuClass = Class.forName("com.znzz.practice.Student");//获取字节码对象
                /*获取构造器*/
                Constructor cons = stuClass.getConstructor(String.class, Integer.class);//如果无参数就是无参构造器
                /*使用构造器反射方法实现对象的创建*/
                Student student = (Student) cons.newInstance("李知恩", 26);//返回Object类型,强制类型转换
                System.out.println(student.getName() + "  " + student.getAge());
    
                System.out.println("构造器的参数个数是:" + cons.getParameterCount());//2
                System.out.println(cons.getModifiers() == Modifier.PUBLIC);//构造器的访问级别 true
                System.out.println(cons.getName());//com.znzz.practice.Student
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
  • Filed和Method类反射编程:Field提供有关类或接口的单个字段信息,以及对它的动态访问权限。

    public class TestFieldAndMethod {
        public static void main(String[] args) {
            try {
                Class<?> stuClass = Class.forName("com.znzz.practice.Student");//加载类
                Student student = (Student) stuClass.newInstance();//通过反射获取一个实例对象
                /*获取某个成员字段*/
                Field nameField = stuClass.getField("name");//获取公共级别的属性字段
                nameField.set(student, "lisa");//为公共字段赋值
                /*使用反射获取某个对象字段的属性值*/
                System.out.println(nameField.get(student));//lisa
    
                /*获取不可见的字段属性private*/
                Field ageField = stuClass.getDeclaredField("age");
                if (ageField.getModifiers() == Modifier.PRIVATE) {
                    /*运行时动态改变私有字段的访问级别*/
                    ageField.setAccessible(true);//访问级别设置为public
                    ageField.set(student, 28);
                    System.out.println(ageField.get(student));//28
                }
    
                Field sexField = stuClass.getDeclaredField("sex");
                if (!sexField.isAccessible()) {
                    sexField.setAccessible(true);
                    sexField.set(student, "女");
                    System.out.println(sexField.get(student));
                }
    
                /*Method反射编程*/
                Book book = new Book();
                book.setName("《红楼梦》");
                Method method = stuClass.getMethod("learn", Book.class);//方法名,参数类型
                method.invoke(student, book);//执行方法
    
                /*获取非公共可见级别的方法*/
                Method method2 = stuClass.getDeclaredMethod("run");
                if (!method2.isAccessible()) {//如果访问级别不是公共可见的
                    method2.setAccessible(true);//运行时更改此方法的访问级别
                    method2.invoke(student);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值