Java反射(Class类,Class对象获取)

目录
  • Java反射超详解
    • 1.反射基础
      • 1.1Class类
      • 1.2类加载
    • 2.反射的使用
      • 2.1Class对象的获取
      • 2.2Constructor类及其用法
      • 2.3Field类及其用法

Java反射超详解

1.反射基础

Java反射机制是在程序的运行过程中,对于任何一个类,都能够知道它的所有属性和方法;对于任意一个对象,都能够知道它的任意属性和方法,这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。

Java反射机制主要提供以下这几个功能:

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所有的成员变量和方法
  • 在运行时调用任意一个对象的方法

1.1Class类

Class类,Class类也是一个实实在在的类,存在于JDK的java.lang包中。Class类的实例表示java应用运行时的类(class ans enum)或接口(interface and annotation)(每个java类运行时都在JVM里表现为一个class对象,可通过类名.class、类型.getClass()、Class.forName("类名")等方法获取class对象)。数组同样也被映射为为class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class 对象。

到这我们也就可以得出以下几点信息:

  • Class类也是类的一种,与class关键字是不一样的。
  • 手动编写的类被编译后会产生一个Class对象,其表示的是创建的类的类型信息,而且这个Class对象保存在同名.class的文件中(字节码文件)。
  • 每个通过关键字class标识的类,在内存中有且只有一个与之对应的Class对象来描述其类型信息,无论创建多少个实例对象,其依据的都是用一个Class对象。
  • Class类只存私有构造函数,因此对应Class对象只能有JVM创建和加载。
  • Class类的对象作用是运行时提供或获得某个对象的类型信息,这点对于反射技术很重要(关于反射稍后分析)。

1.2类加载

类加载机制流程:

类的加载:

注:详细的类加载内容,看JVM板块。

2.反射的使用

2.1Class对象的获取

在类加载的时候,jvm会创建一个class对象。class对象可以说是反射中最常见的。

获取class对象的方式的主要三种:

  • 根据类名:类名.class
  • 根据对象:对象.getClass()
  • 根据全限定类名:Class.forName(全限定类名)
public class demo1Main1 {
    public static void main(String[] args) throws Exception {
        //获取Class对象的三种对象
        System.out.println("根据类名:\t" + User.class);
        System.out.println("根据对象:\t" + new User().getClass());
        System.out.println("根据全限定类名:\t" + Class.forName("demo1.User"));
        //常用的方法
        Class<User> userClass = User.class;
        System.out.println("获取全限定类名:\t" + userClass.getName());
        System.out.println("获取类名:\t" + userClass.getSimpleName());
        System.out.println("实例化:\t" + userClass.newInstance());

    }
}

输出结果:

根据类名: class demo1.User

根据对象: class demo1.User

根据全限定类名: class demo1.User

获取全限定类名: demo1.User

获取类名: User

实例化: User{name='init', age=0}

再来看看Class类的方法:

toString()

public String toString() {
    return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
        + getName();
}

toString()方法能够将对象转换为字符串,toString()首先判断Class类型是否是接口类型,也就是说普通类和接口都能用Class对象表示,然后在判断是否是基本数据类型,这里判断的都是基本数据类型和包装类,还有void类型。

getName()

获取类的全限定名称。(包括包名)即类的完整名称。

  • 如果是引用类型。比如 String.class.getName()→java.lang.String
  • 如果是基本数据类型。比如 byte.class.getName()→byte
  • 如果是数组类型。比如 new Object[3].getClass().getName()→[Ljava.lang.Object;

 getSimpleName()

获取类名(不包括包名)。

getCanonicalName()

获取全限定的类名(包括包名)。

toGenericString()

返回类的全限定名称,而且包括类的修饰符和类型参数信息。

forName()

根据类名获得一个Class对象的引用,这个方法会使类对象进行初始化。

例如:Class t = Class.forName("java.lang.Thread")就能够初始化一个Thread线程对象。

在Java中,一共有三种获取类实例的方式:

Class.forName(java.lang.Thread)
Thread.class
thread.getClass()
newInstance()
创建一个类的实例,代表着这个类的对象。上面forName()方法对类进行初始化,newInstance方法对类进行实例化。使用该方法创建的类,必须带有无参的构造器。

getClassLoader()

获取类加载器对象。

getInterfaces()

获取当前类实现的类或是接口,可能是多个,所以返回的是Class数组。

isInterface()

判断Class对象是否是表示一个接口。

getFields()

获得某个类的所有的公共(public)的字段,包括继承自父类的所有公共字段。 类似的还有getMethods和getConstructors。

getDeclaredFields

获得某个类的自己声明的字段,即包括public、private和proteced,默认但是不包括父类声明的任何字段。类似的还有getDeclaredMethodsgetDeclaredConstructors。

getName、getCanonicalName与getSimpleName的区别:

getSimpleName:只获取类名.
getName:类的全限定名,jvm中Class的表示,可以用于动态加载Class对象,例如Class.forName。
getCanonicalName:返回更容易理解的表示,主要用于输出(toString)或log打印,大多数情况下和getName一样,但是在内部类、数组等类型的表示形式就不同了。

列子:

package com.cry;
public class Test {
    private  class inner{
    }
    public static void main(String[] args) throws ClassNotFoundException {
        //普通类
        System.out.println(Test.class.getSimpleName()); //Test
        System.out.println(Test.class.getName()); //com.cry.Test
        System.out.println(Test.class.getCanonicalName()); //com.cry.Test
        //内部类
        System.out.println(inner.class.getSimpleName()); //inner
        System.out.println(inner.class.getName()); //com.cry.Test$inner
        System.out.println(inner.class.getCanonicalName()); //com.cry.Test.inner
        //数组
        System.out.println(args.getClass().getSimpleName()); //String[]
        System.out.println(args.getClass().getName()); //[Ljava.lang.String;
        System.out.println(args.getClass().getCanonicalName()); //java.lang.String[]
        //我们不能用getCanonicalName去加载类对象,必须用getName
        //Class.forName(inner.class.getCanonicalName()); 报错
        Class.forName(inner.class.getName());
    }
}

2.2Constructor类及其用法

Constructor类存在于反射包(java.lang.reflect)中,反映的是Class 对象所表示的类的构造方法。

获取Constructor对象是通过Class类中的方法获取的,Class类与Constructor相关的主要方法如下:

方法返回值 方法名称 方法说明
Constructor getConstructor(Class<?>… parameterTypes) 返回指定参数类型、具有public访问权限的构造函数对象
Constructor<?>[] getConstructors() 返回所有具有public访问权限的构造函数的Constructor对象数组
Constructor getDeclaredConstructor(Class<?>… parameterTypes) 返回指定参数类型、所有声明的(包括private)构造函数对象
Constructor<?>[] getDeclaredConstructors() 返回所有声明的(包括private)构造函数对象
T newInstance() 调用无参构造器创建此 Class 对象所表示的类的一个新实例。

列子:

public class ConstructionTest implements Serializable {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = null;

        //获取Class对象的引用
        clazz = Class.forName("com.example.javabase.User");

        //第一种方法,实例化默认构造方法,User必须无参构造函数,否则将抛异常
        User user = (User) clazz.newInstance();
        user.setAge(20);
        user.setName("Jack");
        System.out.println(user);

        System.out.println("--------------------------------------------");

        //获取带String参数的public构造函数
        Constructor cs1 =clazz.getConstructor(String.class);
        //创建User
        User user1= (User) cs1.newInstance("hiway");
        user1.setAge(22);
        System.out.println("user1:"+user1.toString());

        System.out.println("--------------------------------------------");

        //取得指定带int和String参数构造函数,该方法是私有构造private
        Constructor cs2=clazz.getDeclaredConstructor(int.class,String.class);
        //由于是private必须设置可访问
        cs2.setAccessible(true);
        //创建user对象
        User user2= (User) cs2.newInstance(25,"hiway2");
        System.out.println("user2:"+user2.toString());

        System.out.println("--------------------------------------------");

        //获取所有构造包含private
        Constructor<?> cons[] = clazz.getDeclaredConstructors();
        // 查看每个构造方法需要的参数
        for (int i = 0; i < cons.length; i++) {
            //获取构造函数参数类型
            Class<?> clazzs[] = cons[i].getParameterTypes();
            System.out.println("构造函数["+i+"]:"+cons[i].toString() );
            System.out.print("参数类型["+i+"]:(");
            for (int j = 0; j < clazzs.length; j++) {
                if (j == clazzs.length - 1)
                    System.out.print(clazzs[j].getName());
                else
                    System.out.print(clazzs[j].getName() + ",");
            }
            System.out.println(")");
        }
    }
}

class User {
    private int age;
    private String name;
    public User() {
        super();
    }
    public User(String name) {
        super();
        this.name = name;
    }

    /**
     * 私有构造
     * @param age
     * @param name
     */
    private User(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

 输出结果:

User{age=20, name='Jack'}
--------------------------------------------
user1:User{age=22, name='hiway'}
--------------------------------------------
user2:User{age=25, name='hiway2'}
--------------------------------------------
构造函数[0]:private com.example.javabase.User(int,java.lang.String)
参数类型[0]:(int,java.lang.String)
构造函数[1]:public com.example.javabase.User(java.lang.String)
参数类型[1]:(java.lang.String)
构造函数[2]:public com.example.javabase.User()
参数类型[2]:()

 关于Constructor类本身一些常用方法如下(仅部分,其他可查API):

方法返回值  方法名称  方法说明
Class  getDeclaringClass()  返回 Class 对象(不包含参数)
Type[]  getGenericParameterTypes()  按照声明顺序返回一组 Type 对象,返回Constructor对象构造函数的形参类型。
String getName()  以字符串形式返回此构造方法的名称。
Class<?>[]   getParameterTypes()  按照声明顺序返回一组 Class 对象,即返回Constructor 对象所表示构造方法形参类型
T newInstance(Object… initargs)  使用此 Constructor对象表示的构造函数来创建新实例
 String toGenericString()   返回描述此 Constructor 的字符串,其中包括类型参数。

 列子:

Constructor cs3 = clazz.getDeclaredConstructor(int.class,String.class);
System.out.println("-----getDeclaringClass-----");
Class uclazz=cs3.getDeclaringClass();
//Constructor对象表示的构造方法的类
System.out.println("构造方法的类:"+uclazz.getName());

System.out.println("-----getGenericParameterTypes-----");
//对象表示此 Constructor 对象所表示的方法的形参类型
Type[] tps=cs3.getGenericParameterTypes();
for (Type tp:tps) {
    System.out.println("参数名称tp:"+tp);
}
System.out.println("-----getParameterTypes-----");
//获取构造函数参数类型
Class<?> clazzs[] = cs3.getParameterTypes();
for (Class claz:clazzs) {
    System.out.println("参数名称:"+claz.getName());
}
System.out.println("-----getName-----");
//以字符串形式返回此构造方法的名称
System.out.println("getName:"+cs3.getName());

System.out.println("-----getoGenericString-----");
//返回描述此 Constructor 的字符串,其中包括类型参数。
System.out.println("getoGenericString():"+cs3.toGenericString());

输出结果:

-----getDeclaringClass-----
构造方法的类:com.example.javabase.User
-----getGenericParameterTypes-----
参数名称tp:int
参数名称tp:class java.lang.String
-----getParameterTypes-----
参数名称:int
参数名称:java.lang.String
-----getName-----
getName:com.example.javabase.User
-----getoGenericString-----
getoGenericString():private com.example.javabase.User(int,java.lang.String)

2.3Field类及其用法

Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。

同样的道理,我们可以通过Class类的提供的方法来获取代表字段信息的Field对象,Class类与Field对象相关方法如下:

方法返回值 方法名称   方法说明
Field  getDeclaredField(String name)  获取指定name名称的(包含private修饰的)字段,不包括继承的字段
Field[]  getDeclaredField()  获取Class对象所表示的类或接口的所有(包含private修饰的)字段,不包括继承的字段
Field  getField(String name)  获取指定name名称、具有public修饰的字段,包含继承字段
Field[]  getField()  获取修饰符为public的字段,包含继承字段

列子:

public class ReflectField {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<?> clazz = Class.forName("reflect.Student");
        //获取指定字段名称的Field类,注意字段修饰符必须为public而且存在该字段,
        // 否则抛NoSuchFieldException
        Field field = clazz.getField("age");
        System.out.println("field:"+field);
        //获取所有修饰符为public的字段,包含父类字段,注意修饰符为public才会获取
        Field fields[] = clazz.getFields();
        for (Field f:fields) {
            System.out.println("f:"+f.getDeclaringClass());
        }
        System.out.println("================getDeclaredFields====================");
        //获取当前类所字段(包含private字段),注意不包含父类的字段
        Field fields2[] = clazz.getDeclaredFields();
        for (Field f:fields2) {
            System.out.println("f2:"+f.getDeclaringClass());
        }
        //获取指定字段名称的Field类,可以是任意修饰符的自动,注意不包含父类的字段
        Field field2 = clazz.getDeclaredField("desc");
        System.out.println("field2:"+field2);
    }
}
class Person{
    public int age;
    public String name;
   //省略set和get方法
}
class Student extends Person{
    public String desc;
    private int score;
    //省略set和get方法
}

  输出结果:

field:public int reflect.Person.age
f:public java.lang.String reflect.Student.desc
f:public int reflect.Person.age
f:public java.lang.String reflect.Person.name

================getDeclaredFields====================
f2:public java.lang.String reflect.Student.desc
f2:private int reflect.Student.score
field2:public java.lang.String reflect.Student.desc

上述方法需要注意的是,如果我们不期望获取其父类的字段,则需使用Class类的getDeclaredField/getDeclaredFields方法来获取字段即可,倘若需要连带获取到父类的字段,那么请使用Class类的getField/getFields,但是也只能获取到public修饰的的字段,无法获取父类的私有字段。下面将通过Field类本身的方法对指定类属性赋值,代码演示如下:

//获取Class对象引用
Class<?> clazz = Class.forName("reflect.Student");

Student st= (Student) clazz.newInstance();
//获取父类public字段并赋值
Field ageField = clazz.getField("age");
ageField.set(st,18);
Field nameField = clazz.getField("name");
nameField.set(st,"Lily");
//只获取当前类的字段,不获取父类的字段
Field descField = clazz.getDeclaredField("desc");
descField.set(st,"I am student");
Field scoreField = clazz.getDeclaredField("score");
//设置可访问,score是private的
scoreField.setAccessible(true);
scoreField.set(st,88);
System.out.println(st.toString());
//输出结果:Student{age=18, name='Lily ,desc='I am student', score=88}
//获取字段值
System.out.println(scoreField.get(st));
// 88
其中的set(Object obj, Object value) 方法是Field类本身的方法,用于设置字段的值,而get(Object obj)则是获取字段的值,当然关于Field类还有其他常用的方法如下:
方法返回值  方法名称  方法说明
void  set(Object obj, Object value)  将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
Object get(Object obj)  返回指定对象上此 Field 表示的字段的值
Class<?>  getType()  返回一个 Class 对象,它标识了此Field 对象所表示字段的声明类型。
boolean  isEnumConstant()  如果此字段表示枚举类型的元素则返回 true;否则返回 false
String  toGenericString()  返回一个描述此 Field(包括其一般类型)的字符串
String  getName()  返回此 Field 对象表示的字段的名称
Class<?> getDeclaringClass()   返回表示类或接口的 Class 对象,该类或接口声明由此 Field 对象表示的字段
void  setAccessible(boolean flag)  将此对象的 accessible 标志设置为指示的布尔值,即设置其可访问性

上述方法可能是较为常用的,事实上在设置值的方法上,Field类还提供了专门针对基本数据类型的方法,如setInt()/getInt()、setBoolean()/getBoolean、setChar()/getChar()等等方法,这里就不全部列出了,需要时查API文档即可。需要特别注意的是被final关键字修饰的Field字段是安全的,在运行时可以接收任何修改,但最终其实际值是不会发生改变的。

方法返回值 方法名称  方法说明
Method  getDeclaredMethod(String name, Class<?>… parameterTypes)  返回一个指定参数的Method对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[]  getDeclaredMethod 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Method  getMethod(String name, Class<?>… parameterTypes)  返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method[]  getMethods()  返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共成员方法。

在通过getMethods方法获取Method对象时,会把父类的方法也获取到,如上的输出结果,把Object类的方法都打印出来了。而getDeclaredMethod/getDeclaredMethods方法都只能获取当前类的方法。我们在使用时根据情况选择即可。下面将演示通过Method对象调用指定类的方法:

Class clazz = Class.forName("reflect.Circle");
//创建对象
Circle circle = (Circle) clazz.newInstance();
//获取指定参数的方法对象Method
Method method = clazz.getMethod("draw",int.class,String.class);
//通过Method对象的invoke(Object obj,Object... args)方法调用
method.invoke(circle,15,"圈圈");
//对私有无参方法的操作
Method method1 = clazz.getDeclaredMethod("drawCircle");
//修改私有方法的访问标识
method1.setAccessible(true);
method1.invoke(circle);
//对有返回值得方法操作
Method method2 =clazz.getDeclaredMethod("getAllCount");
Integer count = (Integer) method2.invoke(circle);
System.out.println("count:"+count);

输出结果:

draw 圈圈,count=15
drawCircle
count:100

在上述代码中调用方法,使用了Method类的invoke(Object obj,Object… args) 第一个参数代表调用的对象,第二个参数传递的调用方法的参数。这样就完成了类方法的动态调用。

方法返回值  方法名称  方法说明
Object invoke(Object obj, Object… args)   对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
Class<?>  getReturnType()  返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型,即方法的返回类型
Type getGenericReturnType()   返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象,也是方法的返回类型。
Class<?>[]  getParameterTypes()  按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。即返回方法的参数类型组成的数组
Type[]  getGenericParameterTypes()  按照声明顺序返回 Type 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型的,也是返回方法的参数类型
String getName()   以 String 形式返回此 Method 对象表示的方法名称,即返回方法的名称
boolean isVarArgs()   判断方法是否带可变参数,如果将此方法声明为带有可变数量的参数,则返回 true;否则,返回 false。

getReturnType方法/getGenericReturnType方法都是获取Method对象表示的方法的返回类型,只不过前者返回的Class类型后者返回的Type(前面已分析过),Type就是一个接口而已,在Java8中新增一个默认的方法实现,返回的就参数类型信息

public interface Type {
    //1.8新增
    default String getTypeName() {
        return toString();
    }
}

而getParameterTypes/getGenericParameterTypes也是同样的道理,都是获取Method对象所表示的方法的参数类型,其他方法与前面的Field和Constructor是类似的。

以上就是Java反射(Class类,Class对象获取)的详细内容,更多关于Java反射的资料请关注我们其它相关文章!,希望大家以后多多支持我们!

(0)

相关推荐

  • Java中的反射机制基本运用详解

    目录 Java中的反射机制基本运用 1.什么是反射(reflect) 2.反射机制提供的功能 3.反射->获取类对象 4.反射->利用无参构造实例化对象 5.反射->利用有参构造实例化对象 6.反射->调用无参方法 7.反射->调用有参方法 8.反射->访问私有方法 9.反射->类加载路径 总结 Java中的反射机制基本运用 看完反射可以了解一下注解 注解annotation://www.jb51.net/article/221276.htm 1.什么是反射(re

  • java反射超详细讲解

    目录 Java反射超详解✌ 1.反射基础 1.1Class类 1.2类加载 2.反射的使用 2.1Class对象的获取 2.2Constructor类及其用法 2.4Method类及其用法 Java反射超详解✌ 1.反射基础 Java反射机制是在程序的运行过程中,对于任何一个类,都能够知道它的所有属性和方法:对于任意一个对象,都能够知道它的任意属性和方法,这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制. Java反射机制主要提供以下这几个功能: 在运行时判断任意一个对象所属

  • java 反射调用Service导致Spring注入Dao失效的解决方案

    目录 java 反射调用Service导致Spring注入Dao失效 问题发生背景: 1.错误方法:通过反射执行service的方法 2.解决方法:通过获取Spring容器取得对象 反射调用导致Spring特性失效 1.抛出问题 1.1.编写TestAspectController类 1.2.编写ModuleService类 1.3.编写TestKey注解 1.4.编写TestAspectService 1.5.编写TestAspect切面 2.解决问题 2.1.编写SpringContextU

  • java反射机制最详解

    目录 java反射机制 什么是反射? 反射的功能: 反射常用类: 1.Class枚举类 2.Constructor构造器 3.Method方法类 4.Field变量类 反射运行指示图 通过反射获取对象 总结 java反射机制 什么是反射? 在java开发中有一个非常重要的概念就是java反射机制,也是java的重要特征之一.反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力,通过反射可以调用私有方法和私有属性,大部分框架也都是运用反射原理的

  • Java反射(JDK)与动态代理(CGLIB)详解

    目录 一.反射 二.动态代理 1.JDK代理 2.CGLIB代理 3.JDK代理与CGLIB代理对比 总结 一.反射 概念:在运行状态中,对于任意的一个类,都能够知道这个类的所有字段和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法 实现方法:JVM在第一次加载某个类时会生成一个Class对象,里面记录了这个类的信息 链接:类加载机制(留坑) 二.动态代理 动态代理的作用:在不改变原代码的基础上增加新的功能,如日志.权限检验等 反射在动态代理中的应用:由于知道原类的字段.方法等信息,才

  • Java反射(Class类,Class对象获取)

    目录 Java反射超详解 1.反射基础 1.1Class类 1.2类加载 2.反射的使用 2.1Class对象的获取 2.2Constructor类及其用法 2.3Field类及其用法 Java反射超详解 1.反射基础 Java反射机制是在程序的运行过程中,对于任何一个类,都能够知道它的所有属性和方法:对于任意一个对象,都能够知道它的任意属性和方法,这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制. Java反射机制主要提供以下这几个功能: 在运行时判断任意一个对象所属的类

  • java反射机制根据属性名获取属性值的操作

    一.考虑安全访问范围内的属性,没有权限访问到的属性不读取 /** * 根据属性名获取属性值 * * @param fieldName * @param object * @return */ private String getFieldValueByFieldName(String fieldName, Object object) { try { Field field = object.getClass().getField(fieldName); //设置对象的访问权限,保证对priva

  • Java反射 PropertyDescriptor类案例详解

    JAVA中反射机制(JavaBean的内省与BeanUtils库) 内省(Introspector) 是Java 语言对JavaBean类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则.如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为"值对象"(Value Object),或"VO".方法比较少.这些信息储存在类的私有变量中,通过set(

  • Java反射机制原理、Class获取方式以及应用场景详解

    目录 学习背景 一.Java反射机制是什么? 1.1 反射原理 1.2 反射例子 二.Java反射机制中获取Class的三种方式及区别? 2.1 Class的几种获取方式 2.2 代码演示几种方式的区别 三.Java反射机制的应用场景有哪些? 3.1 应用场景 3.2 简单工厂模式优化 3.2.1 什么是简单工厂模式? 3.2.2 简单工厂模式有什么用? 3.2.3 如何实现简单工程模式? 3.2.4 简单工厂模式优化 3.2.5 简单工厂模式再次优化 3.3 代理模式中的动态代理实现 3.3.

  • Java反射之类的实例对象的三种表示方式总结

    如下所示: <span style="font-size:14px;">package com.imooc.reflect; public class ClassDemo1 { public static void main(String[] args) { //Foo的实例对象如何表示 Foo foo1 = new Foo();//foo1就表示出来了 //Foo这个类,也是一个实例对象,Class类的实例对象,如何表示呢. //任何一个类都是Class的实例对象,这个实

  • Java重点梳理类与对象核心原理

    目录 前言 一.类与对象的基本关系 二.类与对象的使用 1.类的定义 2.对象的创建 3.对象的使用 4.在类定义内调用方法 三.参数传递 1.以变量为参数调用方法 2.以数组为参数或返回值的方法调用 四.匿名对象 五.本篇总结 前言 在前面的篇章中,对Java语言的简单数据类型.数组.运算符和表达式以及流程控制的方法做了详细介绍.从本章开始,我们正式介绍面向对象的程序设计方法! 面向对象的编程思想是力图使在计算机语言中对事物的描述与现实世界中该事物的本来面目尽可能一致.在面向对象的程序设计中,

  • Java 反射修改类的常量值、静态变量值、属性值实例详解

    前言 有的时候,我们需要修改一个变量的值,但变量也许存在于 Jar 包中或其他位置,导致我们不能从代码层面进行修改,于是我们就用到了下面的场景,通过反射来进行修改变量的值. 定义一个实体类 class Bean{ private static final Integer INT_VALUE = 100; } 利用反射修改私有静态常量方法 System.out.println(Bean.INT_VALUE); Field field = Bean.class.getField("INT_VALUE

  • Java 中的类和对象详情

    目录 1.类的定义 2.类中变量的类型 3.构造方法 4.重载方法 5.继承 5.1 重写方法 6.创建对象 7.访问实例变量和方法 8.比较对象 8.1 使用 == 比较对象 8.2 使用 equals() 比较对象 类可以看成是创建Java对象的模板 1.类的定义 public class Dog { String name; int age; void eat() { } void sleep() { } } 2.类中变量的类型 局部变量:在方法或语句块中定义的变量被称为局部变量.变量声明

  • Java 精炼解读类和对象原理

    面向对象.面向过程 什么是类? 什么是对象? 这是非常抽象的两个概念!!!!!!!! 在说清楚类和对象的概念之前,给大家讲一下什么是面向对象.面向过程,以此来推出我们类和对象的概念. 面向过程:以洗衣服为例:拿盆.放水.放衣服.放洗衣粉.手搓.换水.拧干.晾衣服,这个过程就是面向过程.  面向对象:以洗衣服为例:人把衣服放进洗衣机,倒入洗衣粉,洗完晾干,不需要关心洗衣服整个过程是怎么完成的,只需要找对象,创建对象,使用对象.在好比我们使用toString函数,我们并不关心toString函数具体

  • Java反射 Field类的使用全方位解析

    Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限.反射的字段可能是一个类(静态)字段或实例字段. Field 成员变量的介绍 每个成员变量有类型和值. java.lang.reflect.Field 为我们提供了获取当前对象的成员变量的类型,和重新设值的方法. 获取变量的类型 类中的变量分为两种类型:基本类型和引用类型: 基本类型( 8 种) 整数:byte, short, int, long 浮点数:float, double 字符:char 布尔值:boolean 引用类

随机推荐