这是一个面试问题:
假设您正在为使用JNI和一些C ++代码从串行接口(例如uart)读取数据的Android系统进行编码。
最底层的东西将由C ++代码处理,最终数据将被馈送到Java接口,在此它将被视为String类型。
问题是:假设处理读取的Java代码是这样的:
private void parseSerialData(String input){
if (input==null){
//DO SOMETHING HERE
}
}
是否有可能满足if块的条件?
我对Java的理解告诉我,这是永远不可能的,因为(我可能完全错了)Java中的null是表示“没有引用”的方式,null不是对象,并且不是从类实例化。在DVM或JVM级别,只要声明了变量,就进行引用,即使堆栈上可能没有为其分配内存。
因此,作为方法的参数的局部变量不可能没有引用开头,更不用说稍后提供了指向String对象的引用(即使该对象可能没有引用)信息,它仍然是一个非null的对象),因此if条件将永远不会满足。
但是我不能确定这个问题是否是一个技巧问题,我已经省略了一些内容吗?尤其是考虑到存在C ++,而且我完全不知道将C ++空引用传递给Java是什么感觉?
那么,是否会满足if条件?
答案 0 :(得分:3)
是的,input
当然可以为空。它仅取决于C ++代码的功能。这是一个完整的例子。从您的描述中还不清楚本机方法是返回String还是将其作为参数从本机方法传递给java方法,因此我提供了每个示例。
此程序调用{{1}}五次。前三遍只是传递一个恒定值。接下来的两次等待输入(在本机方法中),然后根据输入是否为空而将null或非null传递给f
。
f
public class Test
{
static {
System.loadLibrary("Test");
}
public static void main(String [] args)
{
Test obj = new Test();
obj.main();
}
void main()
{
f(null);
f("not null");
String s1 = null;
f(s1);
String s2 = n1();
f(s2);
n2();
}
public void f(String s)
{
if (s == null)
System.out.println("null");
else
System.out.println(s);
}
native String n1();
native void n2();
}
#include <stdio.h>
#include <jni.h>
#include "Test.h"
static jstring get_string(JNIEnv *env);
JNIEXPORT jstring JNICALL Java_Test_n1(JNIEnv *env, jobject obj)
{
return get_string(env);
}
JNIEXPORT void JNICALL Java_Test_n2(JNIEnv *env, jobject obj)
{
jstring s = get_string(env);
jclass cls = env->GetObjectClass(obj);
jmethodID f = env->GetMethodID(cls, "f", "(Ljava/lang/String;)V");
env->CallVoidMethod(obj, f, s);
}
static jstring get_string(JNIEnv *env)
{
char buf[20];
if (fgets(buf, sizeof buf, stdin) == NULL)
return NULL;
if (buf[0] == '\n')
return NULL;
return env->NewStringUTF(buf);
}