反射与线程间通讯

反射

一、在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。

注:反射的步骤

A:首先学习字节码文件

B:第二学习获取字节码文件的构造方法,并创建对象

C:有了对象了,就要学会获取对象中的成员变量## 多线程与同步代码块详解

D:能获取对象中的成员变量了,那么还要学习成员方法

二、1)字节码文件的三种获取方式

①Object类的getClass()方法:对象.getClass()

Person p = new Person();
Class c = p.getClass();

注意所有同一个类的字节码文件对象(实例)都是同一个(因为一个类只有唯一的字节码文件)

比如:

Person p = new Person();
Class c = p.getClass();

Person p2 = new Person();
Class c2 = p2.getClass();

System.out.println(p == p2);// false
System.out.println(c == c2);// true

②数据类型的静态的class属性:类名.class;例如:Class c3 = Person.class;

③通过Class类的静态方法forName(String className)(一般只用最后一种,前面两种了解即可)

Class c4 = Class.forName("com.itcast.Person");//通过包路径获取类字节码文件

2)反射获取类的构造方法

  • public Constructor<?>[] getConstructors():所有公共构造方法

  • public Constructor<?>[] getDeclaredConstructors():所有构造方法,包括私有

  • public Constructor<T> getConstructor(Class<?>... parameterTypes):获取单个构造方法

比如:

Class clazz = Class.forName("com.itcast.Person");
Constructor c = clazz.getConstructor(String.class,int.class);//获取有参构造
Person p = (Person) c.newInstance("张三",23);   //通过有参构造创建对象
System.out.println(p);

3)反射获取类的成员变量

  • Field[] fields = c.getFields();// 获取所有公共的成员变量
  • Field[] fields = c.getDeclaredFields();// 获取所有的成员变量
  • Field field = c.getField("age");// 获取单个的成员变量

比如:

Class clazz = Class.forName("com.itcast.Person");
Constructor c = clazz.getConstructor(String.class,int.class);   //获取有参构造
Person p = (Person) c.newInstance("张三",23);                     //通过有参构造创建对象    //修改姓名的值
Field f = clazz.getDeclaredField("name");                       //暴力反射获取字段
f.setAccessible(true);                                          //去除私有权限
f.set(p, "李四"); 
System.out.println(p);

4)反射获取类的成员方法

  • Method[] methods = c.getMethods();// 所有公共方法,包括父类的
  • Method[] methods = c.getDeclaredMethods();// 本类的所有方法
Class clazz = Class.forName("com.heima.bean.Person");
Constructor c = clazz.getConstructor(String.class,int.class);   //获取有参构造
Person p = (Person) c.newInstance("张三",23);                     //通过有参构造创建对象

Method m = clazz.getMethod("eat");                              //获取eat方法
m.invoke(p);

Method m2 = clazz.getMethod("eat", int.class);                  //获取有参的eat方法
m2.invoke(p, 10);

三、案例:动态创建某个配置文件中提供的一个类的名字的这个类的对象,并执行其方法

public class DemoClass {
    public void run() {
        System.out.println("welcome to heima!");
    }
}
//创建输入流关联xxx.properties
BufferedReader br = new BufferedReader(new FileReader("file.properties"));  
Class clazz = Class.forName(br.readLine()); //读取配置文件中类名,获取字节码对象

DemoClass dc = (DemoClass) clazz.newInstance(); //通过字节码对象创建对象
dc.run();//执行方法

四、泛型只是在编译期间(或者是你在写代码期间)强制要求你的做的一些规范,等编译通过生成了字节码文件后,泛型就会被擦除,运行期间就没有泛型了。
五、public void setProperty(Object obj, String propertyName, Object value){},此方法可将obj对象中名为propertyName的属性的值设置为value。

public class Tool {
    //此方法可将obj对象中名为propertyName的属性的值设置为value。
    public void setProperty(Object obj, String propertyName, Object value) throws Exception {
        Class clazz = obj.getClass();                   //获取字节码对象
        Field f = clazz.getDeclaredField(propertyName); //暴力反射获取字段
        f.setAccessible(true);                          //去除权限
        f.set(obj, value);
    }
}

public static void main(String[] args) throws Exception {
    Student s = new Student("张三", 23);
    System.out.println(s);

    Tool t = new Tool();
    t.setProperty(s, "name", "李四");
    System.out.println(s);
}

线程间通讯

多个线程并发执行时,在默认情况下CPU是随机切换线程的,如果我们希望他们有规律的执行, 就可以使用通信。两个线程就用wait() 和notify();多个线程就用wait() 和notifyAll()。

注意事项:

1,这两个方法必须在同步代码中执行, 并且使用同步锁对象来调用。

2,为什么wait方法和notify方法定义在Object这类中?因为锁对象可以是任意对象,Object是所有的类的基类,所以wait方法和notify方法需要定义在Object这个类中。

3,sleep方法和wait方法的区别?

sleep方法必须传入参数,参数就是时间,时间到了自动醒来;wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待。sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡;wait方法在同步函数或者同步代码块中释放锁。

线程组
Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。默认情况下,所有的线程都属于主线程组。

public final ThreadGroup getThreadGroup();//通过线程对象获取他所属于的组

public final String getName();//通过线程组对象获取他组的名字

我们也可以给线程设置分组

1,ThreadGroup(String name) 创建线程组对象并给其赋值名字

2,创建线程对象

3,Thread(ThreadGroup group, Runnable target, String name)

4,设置整组的优先级或者守护线程

多线程程序实现方式

这种方式的好处,可以通过线程方法来返回一个结果,而run方法不能返回结果

public class MyCallable implements Callable<Integer> {
    private int number;

    public MyCallable(int number) {
        this.number = number;
    }
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int x = 1; x <= number; x++) {
            sum += x;
        }
        return sum;
    }   
}

// 创建线程池对象
ExecutorService pool = Executors.newFixedThreadPool(2);

// 可以执行Runnable对象或者Callable对象代表的线程
Future<Integer> f1 = pool.submit(new MyCallable(100));
Future<Integer> f2 = pool.submit(new MyCallable(200));

// V get()
Integer i1 = f1.get();
Integer i2 = f2.get();

System.out.println(i1);
System.out.println(i2);

// 结束
pool.shutdown();

线程的生命周期:新建,就绪,运行,阻塞,死亡

好了今天就先说到这了,想了解更多学习知识,请关注微信公众号“阿Q说”,获取更多学习资料吧!你也可以后台留言说出你的疑惑,阿Q将会在后期的文章中为你解答。每天学习一点点,每天进步一点点。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 进程和线程 进程 所有运行中的任务通常对应一个进程,当一个程序进入内存运行时,即变成一个进程.进程是处于运行过程中...
    胜浩_ae28阅读 5,091评论 0 23
  • 进程和线程 进程 所有运行中的任务通常对应一个进程,当一个程序进入内存运行时,即变成一个进程.进程是处于运行过程中...
    小徐andorid阅读 2,800评论 3 53
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,371评论 0 4
  • 2018,going on …名可名加油! 腾讯的企鹅,京东的狗 去哪的骆驼,途牛的牛 … 越来越多的企业将动物卡...
    翔子0109阅读 230评论 0 0
  • 暑期,和孩子们一起读《绿野仙踪》、读《女巫》。 两本书,两个不同的主角,孩子们对两个主角的差异可以说出不下十条。但...
    做作业的麦子妈阅读 425评论 0 2