【廖雪峰官方网站/Java教程】反射

【廖雪峰Java】Java基础知识 詹姆斯·高斯林(James Gosling)对于float类型,需要加上f后缀。// 科学计数法表示的3.14x10^38// 错误:不带f结尾的是double类型,不能赋值给float。 阅读详情

注:本文参考自:https://www.liaoxuefeng.com/wiki/1252599548343744/1255945147512512
什么是反射?
反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息。
正常情况下,如果我们要调用一个对象的方法,或者访问一个对象的字段,通常会传入对象实例。反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法。

1.Class类

1.1.Class类和反射(reflection)基本概念

除了int等基本类型外,Java的其他类型全部都是class(包括interface)。例如:

String
Object
Runnable
Exception

而class是由JVM在执行过程中动态加载的。JVM在第一次读取到一种class类型时,将其加载进内存。每加载一种class,JVM就为其创建一个Class类型的实例,并关联起来。注意:这里的Class类型是一个名叫Class的class。它长这样:

public final class Class {
    private Class() {}
}

以String类为例,当JVM加载String类时,它首先读取String.class文件到内存,然后,为String类创建一个Class实例并关联起来:

Class cls = new Class(String);

这个Class实例是JVM内部创建的,如果我们查看JDK源码,可以发现Class类的构造方法是private,只有JVM能创建Class实例,我们自己的Java程序是无法创建Class实例的。
所以,JVM持有的每个Class实例都指向一个数据类型(class或interface)。
在这里插入图片描述
一个Class实例包含了该class的所有完整信息:
在这里插入图片描述
由于JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息,包括类名、包名、父类、实现的接口、所有方法、字段等,因此,如果获取了某个Class实例,我们就可以通过这个Class实例获取到该实例对应的class的所有信息。
这种通过Class实例获取class信息的方法称为反射(Reflection)。

1.2.三种方法获取一个class的Class实例

1.2.1.方法1:直接通过一个class的静态变量class获取:

Class cls = String.class;

1.2.2.方法2:实例变量的getClass()方法

如果我们有一个实例变量,可以通过该实例变量提供的getClass()方法获取:

String s = "Hello";
Class cls = s.getClass();

1.2.3.方法3:静态方法Class.forName()获取

如果知道一个class的完整类名,可以通过静态方法Class.forName()获取:

Class cls = Class.forName("java.lang.String");

1.3.Class实例比较

1.3.1.利用"=="比较两个Class实例

因为Class实例在JVM中是唯一的,所以,上述方法获取的Class实例是同一个实例。可以用==比较两个Class实例:

Class cls1 = String.class;

String s = "Hello";
Class cls2 = s.getClass();

boolean sameClass = cls1 == cls2; // true

1.3.2.与instanceof的区别

两者区别如下:

Integer n = new Integer(123);

boolean b1 = n instanceof Integer; // true,因为n是Integer类型
boolean b2 = n instanceof Number; // true,因为n是Number类型的子类

boolean b3 = n.getClass() == Integer.class; // true,因为n.getClass()返回Integer.class
boolean b4 = n.getClass() == Number.class; // false,因为Integer.class!=Number.class

用instanceof不但匹配指定类型,还匹配指定类型的子类。而用"==“判断class实例可以精确地判断数据类型,但不能作子类型比较。
通常情况下,我们应该用instanceof判断数据类型,因为面向抽象编程的时候,我们不关心具体的子类型。只有在需要精确判断一个类型是不是某个class的时候,我们才使用”=="判断class实例。

1.4.数组也是一种Class

注意到数组(例如String[])也是一种Class,而且不同于String.class,它的类名是[Ljava.lang.String。此外,JVM为每一种基本类型如int也创建了Class,通过int.class访问。
如果获取到了一个Class实例,我们就可以通过该Class实例来创建对应类型的实例:

// 获取String的Class实例:
Class cls = String.class;
// 创建一个String实例:
String s = (String) cls.newInstance(); // 相当于 new String()

上述代码相当于new String()。通过Class.newInstance()可以创建类实例,它的局限是:只能调用【public && 无参数】构造方法。带参数的构造方法,或者非public的构造方法都无法通过Class.newInstance()被调用。

1.5.动态加载

JVM在执行Java程序的时候,并不是一次性把所有用到的class全部加载到内存,而是第一次需要用到class时才加载。

2.访问字段

2.1.Class类中访问字段

对任意的一个Object实例,只要我们获取了它的Class,就可以获取它的一切信息。
我们先看看如何通过Class实例获取字段信息。Class类提供了以下几个方法来获取字段:

  • Field getField(name):根据字段名获取某个public的field(包括父类)
  • Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
  • Field[] getFields():获取所有public的field(包括父类)
  • Field[] getDeclaredFields():获取当前类的所有field(不包括父类)

一个Field对象包含了一个字段的所有信息:

  • getName():返回字段名称,类型是String,例如,“name”;
  • getType():返回字段类型,也是一个Class实例,例如,String.class;
  • getModifiers():返回字段的修饰符,它是一个int,不同的bit表示不同的含义。
    以String类的value字段为例,它的定义是:
public final class String {
    private final byte[] value;
}

我们用反射获取该字段的信息,代码如下:

Field f = String.class.getDeclaredField("value");
f.getName(); // "value"
f.getType(); // class [B 表示byte[]类型
int m = f.getModifiers();
Modifier.isFinal(m); // true
Modifier.isPublic(m); // false
Modifier.isProtected(m); // false
Modifier.isPrivate(m); // true
Modifier.isStatic(m); // false

2.2.获取字段值

利用反射拿到字段的一个Field实例只是第一步,我们还可以拿到一个实例对应的该字段的值。
例如,对于一个Person实例,我们可以先拿到name字段对应的Field,再获取这个实例的name字段的值:

// reflection
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws Exception {
        Object p = new Person("Xiao Ming");
        Class c = p.getClass();
        Field f = c.getDeclaredField("name");
        Object value = f.get(p);
        System.out.println(value); // "Xiao Ming"
    }
}

class Person {
    private String name;
    public Person(String name) {
        this.name = name;
    }
}

上述代码先获取Class实例,再获取Field实例,然后,用Field.get(Object)获取指定实例的指定字段的值。
运行代码,如果不出意外,会得到一个IllegalAccessException,这是因为name被定义为一个private字段,正常情况下,Main类无法访问Person类的private字段。要修复错误,可以将private改为public,或者,在调用Object value = f.get§;前,先写一句:

f.setAccessible(true);

调用Field.setAccessible(true)的意思是,别管这个字段是不是public,一律允许访问。
可以试着加上上述语句,再运行代码,就可以打印出private字段的值。

2.3.设置字段值

通过Field实例既然可以获取到指定实例的字段值,自然也可以设置字段的值。
设置字段值是通过Field.set(Object, Object)实现的,其中第一个Object参数是指定的实例,第二个Object参数是待修改的值。示例代码如下:

// reflection
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws Exception {
        Person p = new Person("Xiao Ming");
        System.out.println(p.getName()); // "Xiao Ming"
        Class c = p.getClass();
        Field f = c.getDeclaredField("name");
        f.setAccessible(true);
        f.set(p, "Xiao Hong");
        System.out.println(p.getName()); // "Xiao Hong"
    }
}

class Person {
    private String name;
    public Person(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
}

运行上述代码,打印的name字段从Xiao Ming变成了Xiao Hong,说明通过反射可以直接修改字段的值。
同样的,修改非public字段,需要首先调用setAccessible(true)。

3.调用方法

3.1.Class类中获取Method

我们已经能通过Class实例获取所有Field对象,同样的,可以通过Class实例获取所有Method信息。Class类提供了以下几个方法来获取Method:

  • Method getMethod(name, Class…):获取某个public的Method(包括父类) Method
  • getDeclaredMethod(name, Class…):获取当前类的某个Method(不包括父类) Method[]
  • getMethods():获取所有public的Method(包括父类) Method[]
  • getDeclaredMethods():获取当前类的所有Method(不包括父类)
public class Main {
    public static void main(String[] args) throws Exception {
        Class stdClass = Student.class;
        // 获取public方法getScore,参数为String:
        System.out.println(stdClass.getMethod("getScore", String.class));
        // 获取继承的public方法getName,无参数:
        System.out.println(stdClass.getMethod("getName"));
        // 获取private方法getGrade,参数为int:
        System.out.println(stdClass.getDeclaredMethod("getGrade", int.class));
    }
}

class Student extends Person {
    public int getScore(String type) {
        return 99;
    }
    private int getGrade(int year) {
        return 1;
    }
}

class Person {
    public String getName() {
        return "Person";
    }
}

上述代码首先获取Student的Class实例,然后,分别获取public方法、继承的public方法以及private方法,打印出的Method类似:

public int Student.getScore(java.lang.String)
public java.lang.String Person.getName()
private int Student.getGrade(int)

一个Method对象包含一个方法的所有信息:

  • getName():返回方法名称,例如:“getScore”;
  • getReturnType():返回方法返回值类型,也是一个Class实例,例如:String.class;
  • getParameterTypes():返回方法的参数类型,是一个Class数组,例如:{String.class, int.class};
  • getModifiers():返回方法的修饰符,它是一个int,不同的bit表示不同的含义。

3.2.调用方法(通过反射执行Method)

当我们获取到一个Method对象时,就可以对它进行调用。我们以下面的代码为例:

String s = "Hello world";
String r = s.substring(6); // "world"

如果用反射来调用substring方法,需要以下代码:

public class Main {
    public static void main(String[] args) throws Exception {
        // String对象:
        String s = "Hello world";
        // 获取String substring(int)方法,参数为int:
        Method m = String.class.getMethod("substring", int.class);
        // 在s对象上调用该方法并获取结果:
        String r = (String) m.invoke(s, 6);
        // 打印调用结果:
        System.out.println(r);
    }
}

注意到substring()有两个重载方法,我们获取的是String substring(int)这个方法。思考一下如何获取String substring(int, int)方法。

Method m = String.class.getMethod("substring", int.class, int.class);
// 在s对象上调用该方法并获取结果:
String r = (String) m.invoke(s, 4, 6);

对Method实例调用invoke就相当于调用该方法,invoke的第一个参数是对象实例,即在哪个实例上调用该方法,后面的可变参数要与方法参数一致,否则将报错。

3.3.调用静态方法

如果获取到的Method表示一个静态方法,调用静态方法时,由于无需指定实例对象,所以invoke方法传入的第一个参数永远为null。我们以Integer.parseInt(String)为例:

public class Main {
    public static void main(String[] args) throws Exception {
        // 获取Integer.parseInt(String)方法,参数为String:
        Method m = Integer.class.getMethod("parseInt", String.class);
        // 调用该静态方法并获取结果:
        Integer n = (Integer) m.invoke(null, "12345");
        // 打印调用结果:
        System.out.println(n);
    }
}

3.4.调用非public方法

和Field类似,对于非public方法,我们虽然可以通过Class.getDeclaredMethod()获取该方法实例,但直接对其调用将得到一个IllegalAccessException。为了调用非public方法,我们通过Method.setAccessible(true)允许其调用:

// reflection
import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) throws Exception {
        Person p = new Person();
        Method m = p.getClass().getDeclaredMethod("setName", String.class);
        m.setAccessible(true);
        m.invoke(p, "Bob");
        System.out.println(p.name);
    }
}

class Person {
    String name;
    private void setName(String name) {
        this.name = name;
    }
}

此外,setAccessible(true)可能会失败。如果JVM运行期存在SecurityManager,那么它会根据规则进行检查,有可能阻止setAccessible(true)。例如,某个SecurityManager可能不允许对java和javax开头的package的类调用setAccessible(true),这样可以保证JVM核心库的安全。

3.5.多态

我们来考察这样一种情况:一个Person类定义了hello()方法,并且它的子类Student也覆写了hello()方法,那么,从Person.class获取的Method,作用于Student实例时,调用的方法到底是哪个?

// reflection
import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) throws Exception {
        // 获取Person的hello方法:
        Method h = Person.class.getMethod("hello");
        // 对Student实例调用hello方法:
        h.invoke(new Student());
    }
}

class Person {
    public void hello() {
        System.out.println("Person:hello");
    }
}

class Student extends Person {
    public void hello() {
        System.out.println("Student:hello");
    }
}

运行上述代码,发现打印出的是Student:hello,因此,使用反射调用方法时,仍然遵循多态原则:即总是调用实际类型的覆写方法(如果存在)。上述的反射代码:

Method m = Person.class.getMethod("hello");
m.invoke(new Student());

实际上相当于:

Person p = new Student();
p.hello();

4.调用构造方法

此部分可结合《Java从入门到精通》第16章的内容一起看。
我们通常使用new操作符创建新的实例:

Person p = new Person();

如果通过反射来创建新的实例,可以调用Class提供的newInstance()方法:

Person p = Person.class.newInstance();

调用Class.newInstance()的局限是,它只能调用该类的public无参数构造方法。如果构造方法带有参数,或者不是public,就无法直接通过Class.newInstance()来调用。
为了调用任意的构造方法,Java的反射API提供了Constructor对象,它包含一个构造方法的所有信息,可以创建一个实例。Constructor对象和Method非常类似,不同之处仅在于它是一个构造方法,并且,调用结果总是返回实例:

import java.lang.reflect.Constructor;

public class Main {
    public static void main(String[] args) throws Exception {
        // 获取构造方法Integer(int):
        Constructor cons1 = Integer.class.getConstructor(int.class);
        // 调用构造方法:
        Integer n1 = (Integer) cons1.newInstance(123);
        System.out.println(n1);

        // 获取构造方法Integer(String)
        Constructor cons2 = Integer.class.getConstructor(String.class);
        Integer n2 = (Integer) cons2.newInstance("456");
        System.out.println(n2);
    }
}

通过Class实例获取Constructor的方法如下:

  • getConstructor(Class…):获取某个public的Constructor;
  • getDeclaredConstructor(Class…):获取某个Constructor;
  • getConstructors():获取所有public的Constructor;
  • getDeclaredConstructors():获取所有Constructor。

注意Constructor总是当前类定义的构造方法,和父类无关,因此不存在多态的问题。
调用非public的Constructor时,必须首先通过setAccessible(true)设置允许访问。setAccessible(true)可能会失败。

5.获取继承关系

在1.2小节中总结了获取一个类Class实例的3种方法。

5.1.获取父类的Class

有了Class实例,我们还可以获取它的父类的Class:

public class Main {
    public static void main(String[] args) throws Exception {
        Class i = Integer.class;
        Class n = i.getSuperclass();
        System.out.println(n);
        Class o = n.getSuperclass();
        System.out.println(o);
        System.out.println(o.getSuperclass());
    }
}

运行上述代码,可以看到,Integer的父类类型是Number,Number的父类是Object,Object的父类是null。除Object外,其他任何非interface的Class都必定存在一个父类类型。

5.2.获取interface

由于一个类可能实现一个或多个接口,通过Class我们就可以查询到实现的接口类型。例如,查询Integer实现的接口:

// reflection
import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) throws Exception {
        Class s = Integer.class;
        Class[] is = s.getInterfaces();
        for (Class i : is) {
            System.out.println(i);
        }
    }
}

要特别注意:getInterfaces()只返回当前类直接实现的接口类型,并不包括其父类实现的接口类型。
此外,对所有interface的Class调用getSuperclass()返回的是null,获取接口的父接口要用getInterfaces():

System.out.println(java.io.DataInputStream.class.getSuperclass()); // java.io.FilterInputStream,因为DataInputStream继承自FilterInputStream
System.out.println(java.io.Closeable.class.getSuperclass()); // null,对接口调用getSuperclass()总是返回null,获取接口的父接口要用getInterfaces()

如果一个类没有实现任何interface,那么getInterfaces()返回空数组。

5.3.继承关系

当我们判断一个实例是否是某个类型时,正常情况下,使用instanceof操作符:

Object n = Integer.valueOf(123);
boolean isDouble = n instanceof Double; // false
boolean isInteger = n instanceof Integer; // true
boolean isNumber = n instanceof Number; // true
boolean isSerializable = n instanceof java.io.Serializable; // true

如果是两个Class实例,要判断一个向上转型是否成立,可以调用isAssignableFrom():

// Integer i = ?
Integer.class.isAssignableFrom(Integer.class); // true,因为Integer可以赋值给Integer
// Number n = ?
Number.class.isAssignableFrom(Integer.class); // true,因为Integer可以赋值给Number
// Object o = ?
Object.class.isAssignableFrom(Integer.class); // true,因为Integer可以赋值给Object
// Integer i = ?
Integer.class.isAssignableFrom(Number.class); // false,因为Number不能赋值给Integer

6.动态代理

6.1.静态代码写法

有没有可能不编写实现类,直接在运行期创建某个interface的实例呢?
这是可能的,因为Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface的实例。
什么叫运行期动态创建?听起来好像很复杂。所谓动态代理,是和静态相对应的。我们来看静态代码怎么写:
定义接口:

public interface Hello {
    void morning(String name);
}

编写实现类:

public class HelloWorld implements Hello {
    public void morning(String name) {
        System.out.println("Good morning, " + name);
    }
}

创建实例,转型为接口并调用:

Hello hello = new HelloWorld();
hello.morning("Bob");

6.2.动态代理【未细看】

还有一种方式是动态代码,我们仍然先定义了接口Hello,但是我们并不去编写实现类,而是直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个Hello接口对象。这种没有实现类但是在运行期动态创建了一个接口对象的方式,我们称为动态代码。JDK提供的动态创建接口对象的方式,就叫动态代理。
一个最简单的动态代理实现如下:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method);
                if (method.getName().equals("morning")) {
                    System.out.println("Good morning, " + args[0]);
                }
                return null;
            }
        };
        Hello hello = (Hello) Proxy.newProxyInstance(
            Hello.class.getClassLoader(), // 传入ClassLoader
            new Class[] { Hello.class }, // 传入要实现的接口
            handler); // 传入处理调用方法的InvocationHandler
        hello.morning("Bob");
    }
}

interface Hello {
    void morning(String name);
}

在这里插入图片描述
动态代理实际上是JDK在运行期动态创建class字节码并加载的过程,它并没有什么黑魔法,把上面的动态代理改写为静态实现类大概长这样:

public class HelloDynamicProxy implements Hello {
    InvocationHandler handler;
    public HelloDynamicProxy(InvocationHandler handler) {
        this.handler = handler;
    }
    public void morning(String name) {
        handler.invoke(
           this,
           Hello.class.getMethod("morning"),
           new Object[] { name });
    }
}

其实就是JDK帮我们自动编写了一个上述类(不需要源码,可以直接生成字节码),并不存在可以直接实例化接口的黑魔法。

java编程自学教程(超详细版) JDBC是 Java平台上最重要的技术,是 Java平台的核心技术。JDBC以面向对象思想设计和实现的,它能够把 Java程序和数据库连接起来。JDBC提供了丰富的 SQL语句和数据源接口,它也是连接 Java程序与数据库的桥梁。: SQL语句, SQL查询,优化,多表连接与表的操作, JDBC数据库操作。: Java类、对象、继承、多态、封装、抽象类、接口、继承与多态。: JSP编程和 Servlet编程的概念、特征以及相关技术等。:异常的概念,异常的定义,处理方法。5阶段Java大厂提升技术。 阅读详情

相关推荐

java零基础从入门到精通(全)

目录前言1. 入门知识1.1 java体系1.2 JDK/JRE/JVM区别1.3 编译与运行理解1.4 类体函数细节2. 标识符 前言 java优势 健壮性(JVM(C++语言写的一个虚拟的计算机)、GC(垃圾回收机制)) 多线程并发 可移植性/跨平台 1. 入门知识 1.1 java体系 JavaSE:标准版 JavaEE:企业版 JavaME:微型版 1.2 JDK/JRE/JVM区别 JVM是不能独立安装的。 JRE和JDK都是可以独立安装的 层层嵌套,jvm包括jdk,jdk包括jre

码农研究僧的博客 6万+

Java学习6个阶段,完整Java入门教程学习步骤来了

Java是一门跨平台的面向对象编程语言,应用广泛,尤其在企业级应用开发方面有很高的竞争力。如果你想学习Java编程,那么本篇文章将为你提供一个完整的Java入门教程学习步骤,帮助你从零开始学习Java。

Python966的博客 1万+

汇编语言与USB量产工具开发解析

本文解析了汇编语言在USB量产工具开发中的应用。USB量产工具主要用于批量配置USB设备,包括固件烧录、格式化、信息写入等功能。汇编语言在底层硬件操作中发挥关键作用,如直接控制USB寄存器、编写驱动和精确时序控制。文章通过伪代码示例展示了USB控制器初始化和固件烧录流程,并强调硬件依赖性、安全机制和时序精度等注意事项。开发需严格遵循芯片手册,建议优先使用厂商SDK,避免设备损坏风险。

RulesChen的博客 1024

Java教程 -- 廖雪峰

复习java知识点 Java简介 Java介于编译型语言和解释型语言之间。编译型语言如C、C++,代码是直接编译成机器码执行,解释型语言如Python可以由解释器直接加载源码然后运行,代价就是运行效率太低。而Java是将代码编译成一种“字节码”,它类似于抽象的CPU指令,然后,针对不同平台编写虚拟机,不同平台的虚拟机负责加载字节码并执行,这样就实现了“一次编写,到处运行”的效果。 java的三个不同版本 java的学习路线 安装配置好java环境以后,可以在cmd命令行当中输入 java - vers

毕业才是起点 5436

读书笔记|智能运维系统落地方案

对于互联网公司来说,系统复杂化导致的人工运维成本激增已经是普遍现象,采用智能运维是行之有效的应对策略。智能运维的核心思想是利用算法来处理海量运维数据,积累运维经验,从而代替人工思考判断,以自动化的过程实现风险的预防、发现、定位和处理。而智能运维系统是其中的重中之重,但建设企业应用智能运维系统,不是应用运维部独立规划设计就可以完成的,它需要业务、产品、开发、基础设施运维多部门协同才能顺利实施。 那么,作为运维人员,您是否了解智能运维系统的架构?如果参与规划建设智能运维系统,该怎么着手呢?下面我们立足实际需求

xiaoshuaca的博客 681

python批量生成CAD图纸

python批量生成CAD图纸

轩逸云的博客 1万+

【廖雪峰官方网站/Java教程】泛型

泛型是一种“代码模板”,可以用一套代码套用各种类型。 1.什么是泛型 1.1.泛型入门概念介绍 为了在ArrayList中兼容不同类型等元素,我们必须把ArrayList变成一种模板:ArrayList<T>,代码如下: public class ArrayList<T> { private T[] array; private int size; ...

Allenlzcoder的博客 503

QT5.14.2离线安装包保姆级教程:断网、选组件、避坑全记录

本文详细介绍了QT5.14.2离线安装包的完整流程,特别针对Windows平台开发者提供断网安装、组件选择及避坑指南。作为QT5系列中最后一个免费离线版本,5.14.2具有免注册、全组件离线安装等独特优势,是开源开发者的理想选择。文章涵盖从环境准备到安装后配置的全方位指导,帮助开发者高效完成安装并避免常见问题。

weixin_30924087的博客 577

【廖雪峰官方网站/Java教程】注解

本节我们将介绍Java程序的一种特殊“注释”——注解(Annotation)。 1.使用注解 1.1.注解入门示例 什么是注解(Annotation)?注解是放在Java源码的类、方法、字段、参数前的一种特殊“注释”,如下例子: // this is a component: @Resource("hello") public class Hello { @Inject int n...

Allenlzcoder的博客 736

分布式光纤传感(DFOS)DTS/DAS/DSS 三合一:10公里管线监测实战与数据解读

本文详细介绍了分布式光纤传感(DFOS)技术在10公里管线监测中的实战应用,通过DTS(温度)、DAS(振动)、DSS(应变)三合一系统,实现对管线健康状态的立体感知。文章涵盖工程部署、数据采集、多物理量数据融合及噪声抑制等关键技术,展示了如何通过一根光纤完成复杂监测任务,显著提升管线安全性和维护效率。

weixin_29168153的博客 315

手把手实现STM32+ESP8266+原子云服务器+手机APP应用——第三节-编写STM32程序实现STM32+ESP8266+原子云服务器+手机APP互相通信—远程数据传输及控制灯

接上一篇,本节使用原子云服务器。编写STM32程序实现STM32+ESP8266+原子云服务器+手机APP互相通信—远程数据传输及控制灯。使用的硬件包括:STM32F103(任意其他款系列也可以的)、正点原子ATK-ESP8266、LED灯。实现编写STM32程序代码来传输单片机数据到原子云服务器和手机APP进行显示,同时通过手机APP和原子云服务器可以远程控制单片机,例如本节实现远程点/灭灯,以此可以扩展开发更多的功能。本专栏本系列的相关文章可查看下面链接:

嵌入式阿齐Archie 8414

java教程——反射(一)

概念剖析 反射,顾名思义强调的当然是那个“反”字,在我们搞清楚“反”字之前,我们来讲讲何为“正”,即class字节码在JVM虚拟机中干了什么,正常流程是怎样的。 我么都知道我们写的java代码会经过编译生成 .class 字节码 =》 然后 由 JVM虚拟机 动态加载到内存中 =》那 JVM 总得给这些 .class 文件打上一个印记吧,要不然怎样找得到呢??? 这就涉及到一个 我们 java 代码调用不了,只有 JVM 能调用的类 Class,注意 与你写的 class 区别开来 ,下面我先附上 C

我想月薪过万的博客 318

Python爬虫实战:使用最新技术抓取百度贴吧帖子内容

本文详细介绍了使用Python最新技术抓取百度贴吧帖子的完整流程。通过库,我们实现了高效的异步爬虫,具备JavaScript渲染、智能反爬应对、数据持久化等高级功能。这个爬虫框架具有良好的扩展性,可以根据具体需求进行功能增强。

2201_76125261的博客 777

Java反射的基本理解

1.什么是反射? 我记得网上有个关于反射很通俗的解释: java是个大美女,但大美女有很多事情是规定不让你做的.反射就是把枪,有枪在手,你想让大美女做什么事就做什么事,脱光了都没问题. 正常的解释:Java的反射是指程序在运行期可以拿到一个对象的所有信息。是一种动态获取对象信息以及动态调用对象的方法。最常见的场景就是在动态代理。而动态代理应用最广的地方就是各种框架,比如:Spring。 2.反射的内容和应用 2.1 class对象 反射必定离不开 Class 对象。都知道,代码编写完后是要编译成

我的青春一去不复返 1769

EndNote X9 参考文献附录列表 格式调整

EndNote X9 插入参考文献常见问题总结

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 2569

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

java反射

导读:反射是一项在java中很重要的技术,其他的语言没有反射。 文章目录参考文章讲解,讲的挺好的oracle有关反射文章的讲解廖雪峰的官方网站反射讲解[Java Reflection:神秘的Java反射机制了解一下](https://juejin.im/entry/5b3d6e2fe51d45199940bd39) 参考文章讲解,讲的挺好的 oracle有关反射文章的讲解 廖雪峰的官方网站反射...

自行车的博客 483

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

22.反射获取方法

来自: Java教程 - 廖雪峰的官方网站研究互联网产品和技术,提供原创中文精品教程https://www.liaoxuefeng.com/wiki/1252599548343744 Class类提供了以下几个方法来获取Method: Method getMethod(name, Class...):获取某个public的Method(包括父类) Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类) Metho...

computer408的博客 2262

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

oracle 雪峰,讨论 - 廖雪峰的官方网站

参考官方文档,貌似如果调取的方法包括多个参数,就应该将多个参数作为一个Class数组传入。官方文档参考:例子参考:其中比较相关的几句是:// Calling No argument MethodMethod no_argument_method = cl.getMethod("length", null);System.out.println(" String Method = " + no_ar...

weixin_34996054的博客 167

java loading_Java反射

来源:廖雪峰的官方网站除了int等基本类型外,Java的其他类型全部都是class(包括interface)。例如:StringObjectRunnableException...仔细思考,我们可以得出结论:class(包括interface)的本质是数据类型(Type)。无继承关系的数据类型无法赋值:Number n = new Double(123.456); // OKString s = ...

weixin_42389522的博客 264

Java基础

目录 1.Java基础知识 2.Java数据类型 3.Java反射 4.Java虚拟机(JVM) 5.Java并发 6.JDBC 1.Java基础知识 java 版本区别,java SE是什么,下载JDK时各个名称的含义 - https://blog.youkuaiyun.com/yinghuo110/article/details/80658308 IDEA新手使用教程(详解) -...

789请问的博客 1108

Java学习步骤及路线(超详细)

我学习Java 已经快三年了,在 Java 学习这条路上也踩过无数次的坑,恰巧有小伙伴问我 Java 学习的路线,我想着趁这次机会分享自己学 Java 的路线,希望给小伙伴们一点帮助,避开路上的一些坑,一起进大厂。 首先,我先分享下自己对不同学习方式的理解,小伙伴们可以根据自己情况选择。 看视频系统学习,比如培训机构的课程、MOOC的课程等。看视频的好处就是有老师带着,易于理解和掌握,非常适合初学者。 看书学习,如《Redis设计与实现》、《 Java 并发编程的艺术》,便于了解技术脉络和深入学习

qq_45225238的博客 4万+

Java笔记4-反射(待更)

目录Class 类访问字段调用方法调用构造方法获取继承关系动态代理 笔记摘自 廖雪峰的官方网站-反射 。 反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息。 反射是为了解决在运行期对某个实例一无所知的情况下如何调用其方法的问题。 Class 类 访问字段 调用方法 调用构造方法 获取继承关系 动态代理 ...

River_in_mind的博客 184

【反射】反射获取类对象的三种方式

反射获取类对象的三种方式 Java代码如下: 方式一:        如果我们有一个实例变量,可以通过该实例变量提供的getClass()方法获取:        String s = “Hello”;        Class cls = s.getClass(); 方式二: &nbsp

weixin_45210565的博客 2554

如何通过反射访问一个类的私有方法

通过类的Class实例来获取这个类的所有信息。

行步至春深 632

【实习总结】Java学习最佳实践!

总结在Java学习过程中一些看过的、质量不错的文章。 前言目录**Java基础****Java进阶****编码规范****反射****注解****泛型****多线程****异常****集合框架****JVM相关****Class文件结构****类加载过程****GC垃圾回收原理、策略****Java8新特性****Stream****Lambda****Optional类****方法引用****单元测试****系统设计****设计模式****系统设计理念****Spring相关****常用中间件****K.

青玉白露的博客 1294
上一篇: 推荐系统/计算广告相关资料整理
下一篇: LIHONGYI--Machine Learning 2017Fall学习笔记 (15)Unsupervised Learning:Word Embedding
Allenlzcoder
博客等级 码龄10年 925粉丝 512原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值