精华内容
下载资源
问答
  • java外部类如何调用内部类的属性和方法 解决方法: 直接看代码 public static void main(String[] args) { //调用静态内部类的方式1 TestChild testChild = new TestChild(); testChild.test(); //...

    java外部类如何调用内部类的属性和方法

     

    解决方法:

        直接看代码

    public static void main(String[] args) {

          //调用静态内部类的方式1

          TestChild testChild = new TestChild();

          testChild.test();

          //调用静态内部类的方式2

          TestChild testChild2 = new TestFather.TestChild();

          testChild2.test();

         

          //调用非静态内部类的方式:http://www.yayihouse.com/yayishuwu/chapter/1955

    }

     

    展开全文
  • 前面介绍了,反射调用类的构造方法来创建类的实例对象。一个类的结构包含方法(构造,静态,非静态)和属性(静态和非静态)。按照循环渐进的方式,接下来,介绍反射类中属性和普通的方法。 在这里简单介绍,反射调用...

    前面介绍了,反射调用类的构造方法来创建类的实例对象。一个类的结构包含方法(构造,静态,非静态)和属性(静态和非静态)。按照循环渐进的方式,接下来,介绍反射类中属性和普通的方法。

    在这里简单介绍,反射调用属性和方法会用到的新类,Method类和Field类。

    Method类的常用API

    • getModifiers() : 获取方法的修饰符
    • getName(): 获取到方法的名称
    • getParameterTypes() : 获取到方法的全部参数类型
    • getReturnType(): 获取到方法的返回值类型
    • getException():获取方法中全部抛出的异常
    • invoke(Object obj,Object ... args):反射调用类中的方法

    Field类的常用API:

    • get(Object obj):获取到属性的具体内容
    • set(Object ,Object value):设置指定属性的具体内容
    • getModifiers() : 获取属性的修饰符
    • isAccessible():判断属性是否可以被外部访问
    • setAccessible(boolean flag):设置这属性可以被外部访问。

    案例实战


    1. 定义一个接口

    定义一些行为,作为抽象方法。用于测试,反射调用实现类(覆盖重写的)方法。

    package com.xingen.classdemo;
    
    public interface ClassTestInterface {
        void testMethod(String name,String work);
    }

    2. 构建一个父类

    添加一些属性,进行封装。用于测试,反射调用父类私有属性。

    package com.xingen.classdemo;
    
    import java.lang.reflect.Constructor;
    
    public class ClassTest2 {
        private String name;
        private String work;
    
        /**
         * 构建一个默认的构造方法
         */
        public ClassTest2() {
        }
    
        /**
         * 构建有参数构造方法
         *
         * @param name
         * @param work
         */
        public ClassTest2(String name, String work) {
            this.name = name;
            this.work = work;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getWork() {
            return work;
        }
    
        public void setWork(String work) {
            this.work = work;
        }
    
    }

    3. 创建一个子类

    该子类的作用有以下几点:

    • 继承父类

    • 实现若干接口,覆盖重写抽象方法,例如:testMethod(String name, String work)

    • 定义自己本身的私有属性,例如:age字段

    package com.xingen.classdemo;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class ClassTest3 extends ClassTest2 implements ClassTestInterface {
    
        private int age;
    
        public ClassTest3() {
        }
    
        @Override
        public void testMethod(String name, String work) {
            this.setName(name);
            this.setWork(work);
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            StringBuffer stringBuffer = new StringBuffer();
            if (getName() != null) {
                stringBuffer.append("name: ");
                stringBuffer.append(getName());
                stringBuffer.append("\n");
            }
            if (getWork() != null) {
                stringBuffer.append("work: ");
                stringBuffer.append(getWork());
                stringBuffer.append("\n");
            }
            if (getAge() > 0) {
                stringBuffer.append("age: ");
                stringBuffer.append(getAge());
            }
            return stringBuffer.toString();
        }
    
    }
    

    4. 各种常用的反射场景

    4.1 案例之反射获取父类的信息

    先获取到Class对象,然后调用getSuperclass()获取到父类的Class对象。
    众所众知,单继承,多实现,因此父类只有一个。这里,输出父类所属于的包信息。

        /**
         * 获取父类的信息
         */
        public static void testSuperClass() {
            try {
                Class<?> mClass = ClassTest3.class;
                //获取继承的父类
                Class<?> superClass = mClass.getSuperclass();
                System.out.println("获取继承父类的包路径:\n" + superClass.getName());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    输出结果是:

    获取继承父类的包路径:
    com.xingen.classdemo.ClassTest2

    4.2 案例之反射获取实现接口的信息

    先获取到Class对象,然后调用getInterfaces()获取到全部实现接口的Class数组。因ClassTest3实现了一个接口,所以这里的数组索引值是0。接口的Class对象可以获取到接口中的完整信息,这里输出接口所属于的包信息。

        /**
         * 获取实现接口的信息
         */
        public static void testInterface() {
            try {
                Class<?> mClass = ClassTest3.class;
                /**
                 * 获得全部实现的接口:Class<?>[] getInterfaces()得到的数组中,接口对象顺序和这个对象所表示的类中implements子句中接口名的顺序,是一致的。
                 */
                Class<?>[] interfaceArray = mClass.getInterfaces();
                Class<?> interfaces = interfaceArray[0];
                System.out.println("获取实现接口的包路径: \n" + interfaces.getName());
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    输出结果是:

    获取实现接口的包路径: 
    com.xingen.classdemo.ClassTestInterface

    4.3 案例之反射调用覆盖重写的方法

    先获取Class对象,然后通过getMethod()获取到指定的需要调用的方法。接下来,处理是否需要添加访问权限setAccessible(true),最后通过invoke()进行方法调用。

        /**
         * 测试覆盖重写的方法
         */
        public static void testSuperMethod() {
            try {
                Class<ClassTest3> mClass = ClassTest3.class;
                ClassTest3 instance = mClass.newInstance();
                Method method = mClass.getMethod("testMethod", String.class, String.class);
                if (!method.isAccessible()) {
                    method.setAccessible(true);
                }
                method.invoke(instance, "xinGen", "Android Lirary Developer");
                System.out.println("反射访问覆盖重写的方法:\n " + instance.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    输出结果是:

    反射访问覆盖重写的方法:
    name: xinGen
    work: Android Lirary Developer

    4.4 案例之反射调用本类定义的私有属性

    先获取到Class对象,然后通过getDeclaredField()获取到本类定义的私有属性,再调用setAccessible()赋予访问权限,最后调用set()对私有属性内容修改。

         /**
         * 测试调用本身定义的私有属性
         */
        public static void testSelfField() {
            try {
                Class<ClassTest3> mClass = ClassTest3.class;
                ClassTest3 instance = mClass.newInstance();
                Field field = mClass.getDeclaredField("age");
                field.setAccessible(true);
                field.set(instance, 24);
                System.out.println("反射访问本类中Private修饰的属性:\n " + instance.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    输出结果是:

    反射访问本类中Private修饰的属性:
    age: 24

    4.5 案例之反射调用父类中私有属性

    先获取到Class对象,然后通过getSuperclass()获取到父类的Class对象,再调用getDeclaredField()获取到父类的私有属性,最后调用set(),对私有属性进行内容修改。这里,最后输出修改后的内容。

      /**
         * 测试调用父类私有属性
         */
        public static void testSuperField() {
            try {
                Class<ClassTest3> mClass = ClassTest3.class;
                ClassTest3 instance = mClass.newInstance();
                Field field = mClass.getSuperclass().getDeclaredField("name");
                field.setAccessible(true);
                field.set(instance, "xinGen");
                System.out.println("反射访问父类中Private修饰的属性:\n " + instance.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    输出结果是:

    反射访问父类中Private修饰的属性:
    name: xinGen

    5. 运行main()入口程序

    package com.xingen.classdemo;
    
    public class Client {
    
        public static void main(String[] args) {
            useClassFieldAndMethod();
        }
        /**
         * 使用Class类:读写属性和方法
         */
        public static void useClassFieldAndMethod() {
            ClassTest3.testInterface();
            ClassTest3.testSuperClass();
            ClassTest3.testSuperMethod();
            ClassTest3.testSelfField();
            ClassTest3.testSuperField();
        }
    }

    反射调用属性的归纳总结

    1. 先判断该属性是否public修饰
    2. 若是,则使用getField()获取。
    3. 反之,则判断是否是类本身单独定义属性。
    4. 若是,则使用getDeclaredField()去获取。
    5. 反之,则先通过getSuperclass()获取到父类的Class对象,再去调用getDeclaredField()去获取。

    同理,反射调用方法和调用属性的思路类似。

    本案例的项目代码https://github.com/13767004362/JavaDemo/tree/master/ClassDemo

    展开全文
  • 在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。 public class Message { public static final String CODE_0000 = "错误码0000...

          Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。


    public class Message {
    	public static final String CODE_0000 = "错误码0000";
    	public static final String CODE_0001 = "错误码0001";
    	public static final String CODE_0002 = "错误码0002";
    	public static final String CODE_0003 = "错误码0003";
    
    	public Message(String a){
    		this.getMessageMethod("hello");
    	}
    	public Message(){
    		this.getMessageMethod("nothing");
    	}
    	public String getMessageMethod(String param) {
    		return "this is getMessageMethod.and param is " + param;
    	}
    
    	public String getMessageMethod(String param, int i) {
    		return "this is getMessageMethod.Param is " + param + "," + i;
    	}
    }


    测试类:

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class Test {
    
    	public static void main(String[] args) throws Exception {
    		Class clazz=Class.forName("test.Message");// 这里写清楚包名.类名,否则会找不到
    		
    		System.out.println("---↓---Value-Of-\"CODE_0000\"---↓---");  
    		Object obj=clazz.newInstance();
    		Field fid=clazz.getField("CODE_0000");
    		System.out.println(fid.get(obj));
    		
    		System.out.println("--↓--Use-Method-\"getMessageMethod(String)\"--↓--");  
            String methodName = "getMessageMethod";
            Method method = clazz.getMethod(methodName,String.class);
            Object  value = method.invoke(clazz.newInstance(),"hello");
            System.out.println( value.toString());  
            
    		System.out.println("--↓--Use-Method-\"getMessageMethod(String,int)\"--↓--");  
            method = clazz.getMethod(methodName,String.class,int.class);
            value = method.invoke(clazz.newInstance(),"hello",2);
            System.out.println( value.toString()); 
            
            System.out.println("---↓---getDeclaredFields---↓---");  
    		Field[] fields=clazz.getDeclaredFields();
    		for(int i=0;i<fields.length;i++){  
    	        System.out.println(fields[i].getName()+":"+fields[i].get(clazz.newInstance()));  
    	    } 
              
            System.out.println("---↓---getDeclaredMethods---↓---");  
    		Method[] declaredMethods=clazz.getDeclaredMethods();
    		for(int i=0;i<declaredMethods.length;i++){  
    	        System.out.println(declaredMethods[i].getName());  
    	    } 
    		System.out.println("---↓---getMethods---↓---");  
    		Method[] methods=clazz.getMethods();
    		for(int i=0;i<methods.length;i++){  
    	        System.out.println(methods[i].getName());  
    	    } 
    		System.out.println("---↓---getConstructors---↓---");  
    		Constructor[] constructor=clazz.getConstructors();
    		for(int i=0;i<constructor.length;i++){  
    	        System.out.println(constructor[i].toString());  
    	    } 	
    	}
    }


    输出:

    ---↓---Value-Of-"CODE_0000"---↓---
    错误码0000
    --↓--Use-Method-"getMessageMethod(String)"--↓--
    this is getMessageMethod.and param is hello
    --↓--Use-Method-"getMessageMethod(String,int)"--↓--
    this is getMessageMethod.Param is hello,2
    ---↓---getDeclaredFields---↓---
    CODE_0000:错误码0000
    CODE_0001:错误码0001
    CODE_0002:错误码0002
    CODE_0003:错误码0003
    ---↓---getDeclaredMethods---↓---
    getMessageMethod
    getMessageMethod
    ---↓---getMethods---↓---
    getMessageMethod
    getMessageMethod
    wait
    wait
    wait
    equals
    toString
    hashCode
    getClass
    notify
    notifyAll
    ---↓---getConstructors---↓---
    public test.Message(java.lang.String)
    public test.Message()

    展开全文
  • JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法(类名,方法名,参数类型,返回值类型);对于任意一个对象,都能够调用它任意的一个方法和属性;这种动态获取的信息以及动态调用...
    • 反射的定义及概述

      JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法(类名,方法名,参数类型,返回值类型);对于任意一个对象,都能够调用它任意一个方法属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

       总结来说就是,反射就是把java类中的各种成分映射成一个个   java对象例如:一个类有:成员变量、方法、构造方法,包等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象

    • 反射的相关函数介绍:

      • 获取类的三种方法
        • 第一种方式-->Class.forName("类名字符串")

          • Class c1=Class.forName("com.edu.Student");

        • 第二种方式-->先创建对象,再用对象调用getClass()方法,即实例对象.getClass().返回运行时类

          • Student s=new Student();

          • Class c2 = s.getClass();

        • 第三种方式-->类名.class。返回Class的对象。(每个类都有class属性)

          • Class c2 = s.getClass();    

            (!!!Class类用于表示.class文件(字节码),获取某个类时的前提条件就是获取该类的Class)
      • 获取属性
      • 获取方法
      • 获取构造函数
      • 获取其他信息
    • 具体代码实现:

      • ​​​​​​​引入工程截图
        • ​​​​​​​
      • 获取类的类名
        • ​​​​​​​实体类Student 
          • ​​​​​​​略
        • 获取代码实现
      • 获取类的构造方法
        • ​​​​​​​Student类的构造方法
          • ​​​​​​​
        • 获取的代码实现
          • ​​​​​​​
      • 获取类的方法
        • ​​​​​​​Student类的方法
          • ​​​​​​​
        • 获取的代码实现
          • ​​​​​​​
      • 获取类的属性
        • ​​​​​​​Student类的属性
          • ​​​​​​​
        • 获取属性的代码实现
          • ​​​​​​​
      • 获取类的其他信息
        • ​​​​​​​获取的代码实现
          • ​​​​​​​

    参考文献:

    1. https://blog.csdn.net/sinat_38259539/article/details/71799078
    2. https://blog.csdn.net/ylyang12/article/details/53469957
    3. https://blog.csdn.net/qq_24341197/article/details/77964172

     

     

     

     

     

     

    展开全文
  • this是一个非常灵活关键字,不会...中有许多成员,大部分情况下中直接进行成员调用,但是为了清楚描述调用是本类属性,会用this.属性表示。 class Person{ String name; int age; public Person(){} ...
  • java 调用类的构造函数

    千次阅读 2019-04-03 13:43:52
    一、·定义图书Book,包含属性(全部私有): 书名,作者,出版社,价格,ISBN, 构造函数1:通过参数传递书名给书名属性赋值; 构造函数2:通过参数传递书名、作者给相关属性赋值; 构造函数3:通过参数传递书名、...
  • 这篇主要写一下JNINative开发, 没看JNI基础知识可以去上一篇文章看一下。JNI初识,函数规范,基本数据类型,与之对应签名 这里我们要在Android Studio中进行JNI开发,首先创建一个NDK工程,然后打开cpp目录...
  • 内部类没有使用static关键字修饰,并且和外部类的成员变量和方法属于同一级别,这样的是非静态成员内部类(可以使用权限修饰符修饰,和final、abstract关键字修饰)。 public class Atest { private String name = ...
  • 之前在看Java的类访问权限的时候,书中写道,如果一个类中某个属性被设置为private,那么“ 除了包含该成员的类,其他任何类都无法访问这个成员 ”,但是今天在看内部类的时候发现一个有意思的例子,如下 ...
  • 反射的作用是编写工具(例如eclipse),编写框架,当然对于一般的程序,我们不可能用反射来做这些事,一般反射大多是用于在构建类的实例以及调用类方法及属性。 ok! 了解了反射是什么以及反射的应用领域,那么就来...
  • 原因:当有类的继承时,父类会 先检查子类有无重写本类方法 ,当子类重写父类方法,父类会动态绑定实现多态。而当子类没有重写父类方法时,便会调用父类的原方法,而此时 方法里的this则是指父类本身 ,若此时在这个...
  • Java通过反射调用类中的指定方法、指定属性、指定构造器1.调用指定方法2. 调用指定属性3. 调用指定构造器 1.调用指定方法 通过反射,调用类中的方法,通过Method类完成。步骤: 通过Class类的getMethod(String ...
  • import java.lang.reflect.Method;/** * 通过反射调用类的private方法 * */public class ReflectByInvokePrivate { /** * @param args */ public static void main(String[] args) throws Exception { ...
  • java的继承问题中,当子类与父类有相同的属性,子类重写了父类的某个方法,那么在创建实例的过程中,方法是如何调用及属性值是什么样的呢?package test2; class father{ int i=0; public void m1(){ System...
  • 1、反射是什么    Java中我们编写的代码后缀为"*....Java中在java.lang包下有一个Class类,这个类可以通过其他类的完整类名获取到该类的“.class”文件句柄,然后解析出该类里面的所有属性和方法(包括私有属性和方法

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,831
精华内容 6,732
关键字:

java调用类的属性

java 订阅