A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 罗磊 中级黑马   /  2012-8-5 12:02  /  1380 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Class clazz = Class.forName("cn.heima.reflect.person");
Class clazz = new person().getClass();
Class clazz = person.class;
上面的三条语句都是加载类的 那选那一句最好 我想是第三句 但见老师多写第一句 所以有点蒙
还有这三句话在内存中是如何存在的
请帮忙解释下 要是有内存图就更好啊

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

5 个回复

倒序浏览
三者是一样的,没好坏之分,都是针对个例程序时选择更为适合的方法。
都是获取类的字节码文件。通俗理解就是程序运行后生成的*.class文件。但实质上*.class文件并不是真正的字节码文件,*.class是有特殊编码的文件,你用Class.forName("cn.heima.reflect.person");new person().getClass();person.class;三种方法获取时*.class文件会由二进制重新编码生成才是真正的字节码文件。
所以*.class是存在硬盘的不在内存,你选择的三种方法加载都是存在于内存的方法区的。
回复 使用道具 举报
Class clazz = Class.forName("cn.heima.reflect.person");
有两种返回方式:
(1)如果字节码已经存在可以直接返回
(2)如果字节码还没有加载,先让类加载器加载,然后再返回。
这种将会是以后实际开发中最常用的方式。
回复 使用道具 举报
对,第一句是最好的。
第一句这个方法是按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类已经被加载过,则返回代表该Class的实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。
有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,框架的设计原理就是建立反射基础上的

下面是模拟的一个小框架例子,希望可以帮助你理解
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;

public class Demo {
        public static void main(String[] args) throws Exception {
               

                //加载一个properties文件
                InputStream fis = Demo.class.getResourceAsStream("config.properties");
               
                Properties prop = new Properties();
                prop.load(fis);
                fis.close();               
                String className = prop.getProperty("className");        //通过Key,拿到相对应的value

                //通过反射,拿到的是这个配置文件中的className的实例
                Collection collection = (Collection)Class.forName(className).newInstance();               


                ReflectPoint p1 = new ReflectPoint(3,3);
                ReflectPoint p2 = new ReflectPoint(5,5);
                ReflectPoint p3 = new ReflectPoint(3,3);
               
                collection.add(p1);
                collection.add(p2);
                collection.add(p3);

                System.out.println(collection.size());
        }
}

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 回答的不错

查看全部评分

回复 使用道具 举报
Class clazz = Class.forName("cn.heima.reflect.person");这种方式是看内存中是否有Person类,没有就将Person类加载进内存。
Class clazz = new person().getClass();这种方式就是通过类的实例调用父类(Object)中的getClass()来获取Class的实例,因为一个类的所有实例都对应内存中的一份字节码。
Class clazz = person.class这种方式就是直接通过类名.class的方式放回Class的实例了。.class应该算是类的属性。
其实三种方式没有好坏,具体情况具体分析,选哪种其实没多大的区别。

回复 使用道具 举报
问题解决啊  谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马