栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

暑假java-day16

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

暑假java-day16

文章目录
      • 1.关于Object类中的wait和notify方法(生产者和消费者模式)
      • 2.反射机制概述
        • 1)反射机制有什么用?
        • 2)反射机制的相关类在哪个包下?
        • 3)反射机制的相关重要的类有哪些?
      • 3.获取Class的三种方式
      • 4.通过反射实例化对象
      • 5.通过读属性文件实例化对象
      • 6.Class.forName()可以只让静态代码块执行!
      • 7.获取类路径下文件的绝对路径
      • 8.以流的形式直接返回(路径)
      • 9.资源绑定器
      • 10.反射Field
      • 11.通过反射机制访问对象属性(重点)
      • 12.可变长度参数
      • 13.反射Method
      • 14.通过反射机制调用方法(重点)
      • 15.反射Constructor
      • 16.通过反射机制调用构造方法
      • 17.获取父类和父接口

1.关于Object类中的wait和notify方法(生产者和消费者模式)

第一:wait和notify方法不是线程对象的方法,是java任何一个java对象都有的方法,因为这两个方式是Object类中自带的。
wait方法和notify方法不是通过线程对象调用。
不是这样: t.wait(),也不是这样的:t.notify()
第二:wait()方法作用?
Object o=new Object();
o.wait();
表示:
让正在o对象上活动的线程进入等待状态,无期限等待。
直到被唤醒为止。
o.wait():方法的调用,会让"当前线程(正在o对象上活动的线程)"进入等待状态。
第三:notify()方法作用?
Object o=new Object();
o.notify();
表示:
唤醒正在o对象上等待的线程。

还有一个notifyAll()方法:
这个方法是唤醒o对象上处于等待状态的所有线程。
第四:
wait和notify方法建立在synchronized线程同步的基础之上。
o.wait()方法会让正在o对象上活动的当前线程进入等待状态,并且释放之前占有的o对象的锁。
o.notify()方法只会通知,不会释放之前占有的对象的锁。

模拟生产者和消费者模式

package com.jmpower.javase.thread;

import java.util.ArrayList;
import java.util.List;

public class ThreadTest14 {
    public static void main(String[] args) {
        //创建一个仓库对象,共享的。
        List list=new ArrayList();
        //创建两个线程对象
        //生产者线程
        Thread t1=new Thread(new Producer(list));
        //消费者线程
        Thread t2=new Thread(new Costumer(list));

        t1.setName("生产者线程");
        t2.setName("消费者线程");

        t1.start();
        t2.start();
    }
}
class Producer implements Runnable{
    //仓库
    private List list;

    public Producer(List list) {
        this.list = list;
    }
    @Override
    public void run() {
        //一直生产(使用死循环来模拟一直生产)
        while(true) {
            //对仓库对象list加锁
            synchronized (list){
                if(list.size()>0){//大于0,表示仓库中已经有一个元素了
                    try {
                        //当前线程进入等待状态,并且释放Producer之前占有的list集合的锁。
                        list.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                //线程能执行到这里说明仓库是空的,可以生产
                Object obj=new Object();
                list.add(obj);
                System.out.println(Thread.currentThread().getName()+"--->"+obj);
                //唤醒消费者进行消费
                list.notify();
            }
        }
    }
}
class Costumer implements Runnable{
    //仓库
    private List list;

    public Costumer(List list) {
        this.list = list;
    }
    @Override
    public void run() {
        //一直消费
        while(true){
            synchronized (list){
                if(list.size()==0){
                    try {
                        //仓库空了,消费者线程进入等待,释放list集合的锁
                        list.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                //程序能够执行到这里说明仓库中有数据,进行消费
                Object obj=list.remove(0);
                System.out.println(Thread.currentThread().getName()+"--->"+obj);
                //唤醒生产线程进行生产
                if(list.size()==0) list.notify();
            }
        }
    }
}
2.反射机制概述 1)反射机制有什么用?

通过java语言中的反射机制可以操作字节码文件。
有点类似于黑客。(可以读和修改字节码文件)
通过反射机制可以操作字节码片段。(class文件)

2)反射机制的相关类在哪个包下?

java.lang.reflect.*;

3)反射机制的相关重要的类有哪些?

java.lang.Class: 代表整个字节码,表示一个类型,代表整个类。
java.lang.reflect.Method: 代表字节码中的方法字节码。代表类中的方法。
java.lang.reflect.Constructor: 代表字节码中的构造方法字节码。代表类中的构造方法。
java.lang.reflect.Field: 代表字节码中的属性字节码。代表类中的成员变量(静态变量和成员变量)。

    java.lang.Class:
        public class User{
            //Field
            int no;

            //Constructor
            public User(){
            }
            public User(int no){
                 this.no=no;
            }

            //Method
            public void doSome(){
            }
3.获取Class的三种方式

三种方式:
第一种: Class c=Class.forName(“完整类名带包名”);
第二种: Class c=对象.getClass();
第三种: Class c=任何类型.class;

package com.jmpower.javase.reflect;

import java.util.Date;

public class ReflectTest01 {
 public static void main(String[] args) {
     
     Class c1=null;
     Class c2=null;
     try {
         c1=Class.forName("java.lang.String");//c1代表String.class文件,或者说c1代表String类
         c2=Class.forName("java.util.Date");//c2代表Date类
         Class c3=Class.forName("java.lang.Integer");//c3代表Integer类型
         Class c4=Class.forName("java.lang.System");//c4代表System类型
     } catch (ClassNotFoundException e) {
         e.printStackTrace();
     }

     //java种任何一个对象都有一个方法: getClass()
     String s="abc";
     Class x=s.getClass();
     System.out.println(x);//x代表String.class字节码文件,x代表String类型
     System.out.println(c1==x);//true(==判断的是对象的内存地址)

     Date time=new Date();
     Class y=time.getClass();
     System.out.println(c2==y);//true(c2和y两个变量种保存的内存地址都是一样的,都指向方法区中的字节码文件)

     //第三种方式: java语言种任何一种类型,包括基本数据类型,他都有.class属性
     Class z=String.class;//z代表String类型
     Class k=Date.class;//k代表Date类型
     Class e=int.class;//e代表int类型
     Class d=Double.class;//d代表Double类型

     System.out.println(x==z);//true
     System.out.println(d);
 }
}
4.通过反射实例化对象
package com.jmpower.javase.reflect;
import com.jmpower.javase.bean.User;


public class ReflectTest02 {
    public static void main(String[] args) {
        //这是不使用反射机制,创建对象
        User user=new User();
        System.out.println(user);

        //下面是使用反射机制创建对象
        try {
            //通过反射机制,获取Class,通过Class来实例化对象
            Class c=Class.forName("com.jmpower.javase.bean.User");
            //newInstance()方法会调用User这个类的无参数构造方法,来完成对象的创建
            //重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
            Object obj=c.newInstance();
            
            System.out.println(obj);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }
}
5.通过读属性文件实例化对象
package com.jmpower.javase.reflect;

import java.io.FileReader;
import java.util.Properties;

public class ReflectTest03 {
    public static void main(String[] args) throws Exception {
        //这种方式代码就写死了,只能创建一个User类型的对象。
        //User user=new User();

        //以下代码是灵活的,代码不需要改动,可以修改配置文件,配置文件修改之后,可以创建出不同的实例对象
        //通过IO流读取class.properties文件
        FileReader reader=new FileReader("C:\Users\Jm\IdeaProjects\untitled47\class.properties");
        //创建属性类对象Map
        Properties pro=new Properties();
        //加载
        pro.load(reader);
        //关闭流
        reader.close();

        //通过key获取value对象
        String className=pro.getProperty("className");
        //System.out.println(className);

        //通过反射机制实例化对象
        Class c=Class.forName(className);
        Object obj=c.newInstance();
        System.out.println(obj);
    }
}
6.Class.forName()可以只让静态代码块执行!
package com.jmpower.javase.reflect;


public class ReflectTest04 {
    public static void main(String[] args) {
        try {
            //class.forName()这个方法执行会导致: 类加载
            Class.forName("com.jmpower.javase.reflect.MyClass");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
class MyClass {
    static {
        System.out.println("类加载,进行静态代码块");
    }
}
7.获取类路径下文件的绝对路径
package com.jmpower.javase.reflect;


public class AboutPath {
    public static void main(String[] args) {
        //这种方式的路径缺点是:移植性差,在IDEA中默认的当前路径是project的根。
        //这个代码假设离开了IDEA,换到了其他位置,可能当前路径就不是project的根了,这时这个
        //FileReader reader=new FileReader("");

        //接下来说一种比较通用的一种路径。即使代码换位置了,就这样编写依然是通用的。
        //注意: 使用以下通用的方式的前提是: 这个文件必须在类路径下。
        //什么类路径下?方式在src下的都是类路径下。
        //src是类的根路径。
        

        String path=Thread.currentThread().getContextClassLoader()
                .getResource("class.properties").getPath();//这种方式获取文件绝对路径是通用的。

        //采用以上的代码可以拿到一个文件的绝对路径。
        ///C:/Users/Jm/IdeaProjects/untitled45/out/production/untitled47/class.properties
        System.out.println(path);

        //获取db.properties文件的绝对路径(从类的根路径下作为起点开始)
        String path2=Thread.currentThread().getContextClassLoader()
                .getResource("com/jmpower/javase/reflect/db.properties").getPath();
        System.out.println(path2);
    }
}
8.以流的形式直接返回(路径)
package com.jmpower.javase.reflect;

import java.io.InputStream;
import java.util.Properties;

public class IoPropertiesTest {
    public static void main(String[] args) throws Exception {
        //获取一个文件的绝对路径!!!
        

        InputStream reader=Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("class.properties");
        Properties pro=new Properties();
        pro.load(reader);
        //通过key获取value
        String className=pro.getProperty("className");
        System.out.println(className);
    }
}
9.资源绑定器
package com.jmpower.javase.reflect;

import java.util.ResourceBundle;

public class ResourceBundleTest {
    public static void main(String[] args) {
        //资源绑定器,只能绑定xxx.properties文件。并且这个文件必须在类路径下。文件扩展名也必须是properties
        //并且在写路径的时候,路径后面的扩展名不能写。
        ResourceBundle bundle=ResourceBundle.getBundle("com/jmpower/javase/reflect/db");

        String className=bundle.getString("className");
        System.out.println(className);
    }
}
10.反射Field
package com.jmpower.javase.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;


public class ReflectTest05 {
    public static void main(String[] args) throws Exception{
        //获取整个类
        Class studentClass=Class.forName("com.jmpower.javase.bean.Student");

        String className=studentClass.getName();
        System.out.println("完整类名: "+className);

        String simpleName=studentClass.getSimpleName();
        System.out.println("简类名: "+simpleName);

        //获取类中所有的public修饰的Field
        Field[] fields=studentClass.getFields();
        System.out.println(fields.length);//2
        //取出这个Field
        Field f=fields[0];
        String fieldName=f.getName();
        System.out.println(fieldName);

        //获取类中所有的Field
        Field[] fs=studentClass.getDeclaredFields();
        System.out.println(fs.length);
        System.out.println("====================================");
        //遍历
        for(Field field:fs){
            //获取属性的修饰符列表
            int i=field.getModifiers();//返回的修饰符是一个数字,每个数字是修饰符的代号!
            //可以将这个"代号"数字转换成"字符串"吗?
            String modifierString= Modifier.toString(i);
            System.out.print(modifierString+" ");

            //获取属性的类型
            Class fieldType=field.getType();
            //String fName=fieldType.getName();
            String fName=fieldType.getSimpleName();
            System.out.print(fName+" ");

            //获取属性的名字
            System.out.println(field.getName());
        }
    }
}
11.通过反射机制访问对象属性(重点)
package com.jmpower.javase.reflect;

import com.jmpower.javase.bean.Student;

import java.lang.reflect.Field;


public class ReflectTest06 {
    public static void main(String[] args) throws Exception {
        
        Student s=new Student();
        //给属性赋值
        s.no=1111;
        //读取属性的值
        System.out.println(s.no);


        //使用反射机制,怎么去访问一个对象的属性。(set get)
        
        Class studentClass=Class.forName("com.jmpower.javase.bean.Student");
        Object obj=studentClass.newInstance();//obj就是Student对象(底层调用无参数构造方法)

        //获取no属性(根据属性的名称来获取Field)
        Field noField=studentClass.getDeclaredField("no");
        //给obj对象(Student对象)的no属性赋值
        noField.set(obj,2222);//给obj对象的no属性赋值2222
        //读取obj对象的属性no的值
        System.out.println(noField.get(obj));

        //可以访问私有属性吗?
        Field nameField=studentClass.getDeclaredField("name");

        //打破封装(反射机制的特点: 打破封装,可能会给不法分子留下机会)
        //这样设置之后,在外面也是可以访问private的
        nameField.setAccessible(true);

        //给name属性赋值
        nameField.set(obj,"jackson");
        //获取name属性的值
        System.out.println(nameField.get(obj));
    }
}
12.可变长度参数
package com.jmpower.javase.reflect;

public class ArgsTest {
    public static void main(String[] args) {
        m();
        m(10);
        m(10,20);

        //编译报错
        //m("abc");
        m2(10);
        m2(20,"a");
        m2(20,"a","b");

        m3("a");
        m3("a","b");
        m3("a","b","c");

        String[] strs={"我","是","帅","哥"};
        m3(strs);//没必要

        m3("我","是","帅","哥");


    }
    public static void m(int... args){
        System.out.println("m方法执行了!");
    }
    public static void m2(int a,String... args){
        System.out.println("m2方法执行了!");
    }
    public static void m3(String... args){
        //args有length属性,说明是一个数组!
        //可以将可变长度参数当作一个数组来看
        System.out.println("m3方法执行了!");
        for(int i=0;i
            System.out.print(args[i]+" ");
        }
        System.out.println();
    }
}
13.反射Method
package com.jmpower.javase.reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectTest07 {
    public static void main(String[] args) throws Exception{
        //获取类
        Class userServiceClass=Class.forName("com.jmpower.javase.bean.userService");

        //获取所有的Method(包括私有的)
        Method[] methods=userServiceClass.getDeclaredMethods();
        //System.out.println(methods.length);// 2

        //遍历Method
        for(Method method:methods){
            //获取修饰符列表
            System.out.println(Modifier.toString(method.getModifiers()));
            //获取返回值类型
            System.out.println(method.getReturnType().getSimpleName());
            //获取方法名
            System.out.println(method.getName());
            //方法的修饰符列表(一个方法的参数可能有多个)
            Class[] parameterTypes=method.getParameterTypes();
            for(Class parameterType:parameterTypes){
                System.out.println(parameterType.getSimpleName());
            }
        }
    }
}
14.通过反射机制调用方法(重点)
package com.jmpower.javase.reflect;

import com.jmpower.javase.bean.userService;

import java.lang.reflect.Method;


public class ReflectTest08 {
    public static void main(String[] args) throws Exception{
        //不使用反射机制,怎么调用方法
        //创建对象
        userService userService=new userService();
        //调用方法
        int maxn=userService.ma(99,100);
        System.out.println(maxn);

        //使用反射机制来调用一个对象的方法该怎么做?
        Class userServiceClass=Class.forName("com.jmpower.javase.bean.userService");
        //创建对象
        Object obj=userServiceClass.newInstance();
        //获取Method
        Method loginMethod=userServiceClass.getDeclaredMethod("login", String.class, String.class);
        Object retMax=loginMethod.invoke(obj,"123","lbk");
        System.out.println(retMax);
    }
}
15.反射Constructor
package com.jmpower.javase.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

public class ReflectTest09 {
    public static void main(String[] args) throws Exception{
        StringBuilder s=new StringBuilder();
        Class vipClass=Class.forName("com.jmpower.javase.bean.Vip");
        s.append(Modifier.toString(vipClass.getModifiers()));
        s.append(" class ");
        s.append(vipClass.getSimpleName());
        s.append("{n");

        //拼接构造方法
        Constructor[] constructors=vipClass.getDeclaredConstructors();
        for(Constructor constructor:constructors){
            //public Vip(int name, int price, int value) {
            s.append("t");
            s.append(Modifier.toString(vipClass.getModifiers()));
            s.append(" ");
            s.append(vipClass.getSimpleName());
            s.append("(");
            //拼接参数
            Class[] parameterTypes=constructor.getParameterTypes();
            for(Class parameterType:parameterTypes){
                s.append(parameterType.getSimpleName());
                s.append(",");
            }
            //删除最后下标位置上的字符
            if(parameterTypes.length>0) {
                s.deleteCharAt(s.length()-1);
            }
            s.append("){}n");
        }
        s.append("}");

        System.out.println(s);
    }
}
16.通过反射机制调用构造方法
package com.jmpower.javase.reflect;

import java.lang.reflect.Constructor;

public class ReflectTest10 {
    public static void main(String[] args) throws Exception{
        //使用反射机制创建对象
        Class c=Class.forName("com.jmpower.javase.bean.Vip");
        //调用无参数构造方法
        Object obj=c.newInstance();
        System.out.println(obj);

        //调用有参数构造方法
        //第一步: 先获取这个参数的构造方法
        Constructor con=c.getDeclaredConstructor(String.class,int.class,int.class);
        //第二步: 调用构造方法new对象
        Object newObject=con.newInstance("jackson",100,200);
        System.out.println(newObject);

        //获取无参数构造方法
        Constructor con2=c.getDeclaredConstructor();
        Object newObject2=con2.newInstance();
        System.out.println(newObject2);

    }
}
17.获取父类和父接口
package com.jmpower.javase.reflect;


public class ReflectTest11 {
    public static void main(String[] args) throws Exception{
        //String举例
        Class stringClass=Class.forName("java.lang.String");

        //获取String的父类
        Class superClass=stringClass.getSuperclass();
        System.out.println(superClass.getName());

        //获取String类实现的所有接口(一个类可以实现多个接口)
        Class[] interfaces=stringClass.getInterfaces();
        for(Class in:interfaces){
            System.out.println(in.getName());
        }
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021227.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号