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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张开开 黑马帝   /  2012-2-29 11:35  /  2020 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class.forName();的用法,希望写得详细点,谢谢

评分

参与人数 1黑马币 +3 收起 理由
老罗 + 3

查看全部评分

5 个回复

倒序浏览
Class.forName();返回的是一个类,
作用是要求JVM查找并加载指定的类,
也就是说JVM会执行该类的静态代码段
其它的懵懂中~
回复 使用道具 举报

import java.lang.reflect.*;

public class ReflectTest {

                public static void main(String[] args) throws Exception {
               
                String str1 = "abc";
                Class cls1 = str1.getClass();
                Class cls2 = String.class;
                Class cls3 = Class.forName("java.lang.String");
               
                // class 的一些应用
                System.out.println(cls1 == cls2);
                System.out.println(cls2 == cls3);//都是一份字节码
        
                System.out.println(cls1.isPrimitive());//String不是基本类型字节码 原始类型
                System.out.println(int.class.isPrimitive()); //int 是基本类型字节码
                System.out.println(int.class == Integer.class);//Intger 不是基本类型字节码
                System.out.println(int.class == Integer.TYPE);  //Integer.TYPE是基本类型字节码
                System.out.println(int[].class.isPrimitive());// 数组 不是原始类型
                System.out.println(" 判断是不是数组 " + int[].class.isArray()); //判断class是不是 数组
               
                //构造方法 constructor
                //new String(new StringBuffer("abc"));
                Constructor constructor1 = String.class.getConstructor(StringBuffer.class);//选择构造方法
                String str2 = (String)constructor1.newInstance(new StringBuffer("abc"));//用这个构造方法的同时也传个参数
            System.out.println(str2.charAt(0));//这就是 反射
            
            RflectPoint pt1 = new RflectPoint(3,5);
            Field fieldY = pt1.getClass().getField("y");
            //fieldY的值是多少呢? 是5 错!fieldY不是对象上的变量,而是类上,要用它去取某个对象上对应的值
            System.out.println(fieldY.get(pt1));
            
            Field fieldX = pt1.getClass().getDeclaredField("x");
            fieldX.setAccessible(true);//暴力反射
            System.out.println(fieldX.get(pt1));
            
            changeStringValue(pt1);
            System.out.println(pt1);
            
            //str1.charAt(1); 这就是用反射的方式得到这个字节码里面的方法,在用这个方法去作用某个对象
            Method methodCharAt = String.class.getMethod("charAt", int.class);
            //methodCharAt.invoke(str1, 1);
            System.out.println(methodCharAt.invoke(str1, 1));//invoke 就是调用这个方法
            System.out.println(methodCharAt.invoke(str1, new Object[]{2}));  //jdk 1.4 的方式调用
        }

        private static void changeStringValue(Object obj) throws Exception {
                // TODO Auto-generated method stub
                Field[] fields = obj.getClass().getFields();
                for(Field field:fields){
                        //if(field.getType().equals(String.class)){
                        if(field.getType() == String.class){//这里应该用==号
                               
                                String oldValue = (String)field.get(obj);
                                   String newValue = oldValue.replace('b', 'a');
                            field.set(obj, newValue);
                        }
                }
               
               
        }

}

评分

参与人数 1技术分 +2 收起 理由
老罗 + 2

查看全部评分

回复 使用道具 举报
主要功能
Class.forName(xxx.xx.xx)返回的是一个类
Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,
也就是说JVM会执行该类的静态代码段

给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它?你第一想到的肯定是new,但是注意一点:
A a = (A)Class.forName(“pacage.A”).newInstance();
这和你 A a = new A(); 是一样的效果。

在工场模式,数据库开发还有读写xml文件的时候要经常用到class.forName();
例如:
class c = Class.forName(“Example”);
factory = (ExampleInterface)c.newInstance();

其中ExampleInterface是Example的接口,可以写成如下形式:
String className = “Example”;
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
等你学到JDBC的时候就会用得比较多了,具体的用法这里就不再描述了

评分

参与人数 1技术分 +2 收起 理由
老罗 + 2

查看全部评分

回复 使用道具 举报
Class.forName是用来获取Class的类类型
例如:class myclass
{
int Point;
public static void main(String[] args)
{

Class obj=Class.forName(myclass);
System.out.println(obj.getClassName());
//输出为"myclass";
}
}
用到数据库就是用来加载驱动。
例如:用sql数据库建立jdbc-odbc桥
Class.forName("sun.Jdbc.Odbc.JdbcOdbc");
创建连接
Connection=DriverManager.getConnection("jdbc:odbc:ODBC");
ODBC为你建立的ODBC名  

比如:
        Class c =Class.forName("ss.dd.bb.Bean"); Bean b = c.newInstace();
   和 Bean b = new Bean();效果一样

      但是:forName("ss.bb.bean"), JVM会在classapth中去找对应的类,设定在classpath的类,在java启动的时候最先被加载,并将Class对象保存起来,这样forName创建对象时就不需要通过classloader再去读取该类的文件了。而new 一个对象,一般不需要该类在classpath中设定,但可能需要通过classlaoder来加载。
       当你确定此时内存中没有这个对象的时候,你就可以用class.forName();来创建一个对象,而假如new是不管你内存中是否有这个对象都会创建一个新的对象,也是说会在内存中开辟一个新的内存空间!


【用法】

     Class aClass = Class.forName(xxx.xx.xx);
  Object anInstance = aClass.newInstance();
  Class.forName("").newInstance()返回的是object
  but there is some limit for this method to create instance
  that is your class constructor should no contain parameters, and you should cast the instance manually.
  Class Driver{
  protected static Driver current;
  public static Driver getDriver(){
  return current;
  }
  }
  Class MyDriver extends Driver{
  static{
  Driver.current=new MyDriver();
  }
  MyDriver(){}
  }
  用时:
  Class.forName("MyDriver");
  Driver d=Driver.getDriver();
  有的jdbc连接数据库的写法里是Class.forName(xxx.xx.xx);而有一些:Class.forName(xxx.xx.xx).newInstance(),为什么会有这两种写法呢?
  Class.forName(xxx.xx.xx) 返回的是一个类,
  .newInstance() 后才创建一个对象
  Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
  在JDBC规范中明确要求这个Driver类必须向DriverManager注册自己,即任何一个JDBC Driver的Driver类的代码都必须类似如下:
  public class MyJDBCDriver implements Driver {
  static {
  DriverManager.registerDriver(new MyJDBCDriver());
  }
  }
  所以我们在使用JDBC时只需要Class.forName(XXX.XXX);就可以了
  we just want to load the driver to jvm only, but not need to user the instance of driver, so call Class.forName(xxx.xx.xx) is enough, if you call Class.forName(xxx.xx.xx).newInstance(), the result will same as calling Class.forName(xxx.xx.xx), because Class.forName(xxx.xx.xx).newInstance() will load driver first, and then create instance, but the instacne you will never use in usual, so you need not to create it.
  在JDBC驱动中,有一块静态代码,也叫静态初始化块,它执行的时间是当class调入到内存中就执行(你可以想像成,当类调用到内存后就执行一个方法)。所以很多人把jdbc driver调入到内存中,再实例化对象是没有意义的

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1

查看全部评分

回复 使用道具 举报
  1. public static Class<?> forName(String className)
  2.                 throws ClassNotFoundException {
  3.         return forName0(className, true, ClassLoader.getCallerClassLoader());
  4.     }
复制代码
  1. public static Class<?> forName(String name, boolean initialize,
  2.                                    ClassLoader loader)
  3.         throws ClassNotFoundException
  4.     {
  5.         if (loader == null) {
  6.             SecurityManager sm = System.getSecurityManager();
  7.             if (sm != null) {
  8.                 ClassLoader ccl = ClassLoader.getCallerClassLoader();
  9.                 if (ccl != null) {
  10.                     sm.checkPermission(
  11.                         SecurityConstants.GET_CLASSLOADER_PERMISSION);
  12.                 }
  13.             }
  14.         }
  15.         return forName0(name, initialize, loader);
  16.     }
复制代码
  1.     private static native Class<?> forName0(String name, boolean initialize,
  2.                                             ClassLoader loader)
  3.         throws ClassNotFoundException;
复制代码
可以大胆想像一下,forName 方法其实 先使用 classLoader 加载指定的类 ,然后返回她的Class

评分

参与人数 1技术分 +2 收起 理由
老罗 + 2

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马