有没有可能;把戏;一个Java程序把任何字符串误认为null?
这是一个采访问题: 假设您正在编写一个Android系统,该系统使用JNI和一些C++代码从串行接口读取数据(例如,UART)。有没有可能;把戏;一个Java程序把任何字符串误认为null?,java,android,c++,java-native-interface,Java,Android,C++,Java Native Interface,这是一个采访问题: 假设您正在编写一个Android系统,该系统使用JNI和一些C++代码从串行接口读取数据(例如,UART)。 底层的东西将被C++代码所处理,最终数据将被输入到java接口,在那里它将被当作类型字符串。p> 问题是:假设处理读取的Java代码如下所示: private void parseSerialData(String input){ if (input==null){ //DO SOMETHING HERE } } 是否有可能满足if模块的条件 我对Jav
底层的东西将被C++代码所处理,最终数据将被输入到java接口,在那里它将被当作类型字符串。p> 问题是:假设处理读取的Java代码如下所示:
private void parseSerialData(String input){
if (input==null){
//DO SOMETHING HERE
}
}
是否有可能满足if模块的条件
我对Java的理解告诉我,它永远不可能实现,因为(我可能完全错了)Java中的null是命名“没有引用”的方式,null不是对象,也不是从类实例化的。在DVM或JVM级别,只要声明了变量,就会进行引用,即使堆栈上可能没有为其分配内存
因此,作为方法参数的局部变量不可能一开始就没有引用,更不用说后来给了它一个指向字符串对象的引用(即使该对象可能没有任何信息,但它是非空对象),因此,永远不会满足if条件
但是我不能确定这个问题是否是一个技巧性问题,我遗漏了什么?特别是考虑到C++中存在C++,并且我不知道把C++空引用传递给java是什么样的,如果它有意义的话?
那么,是否满足if条件呢?是的,当然
输入可以为空。它只取决于C++代码所做的。这是一个完整的例子。从您的描述中不清楚本机方法是返回字符串还是将其作为参数从本机方法传递给java方法,因此我提供了每个方法的示例
此程序调用f
五次。前三次只是传递一个常量值。以下两次等待输入(在本机方法中),并根据输入是否为空,将null或非null传递给f
Test.java
Test.cc
如果JNI环境无法为字符串
分配存储,则可能会出现问题,例如返回NULL。这就提出了一个问题,为什么不直接返回字节数组并让Java将其转换为字符串
?java比C++更能更好地处理java <代码>字符串< />代码。我无法想象,在C++中,字符编码会比java更容易。如果声明变量,那么除非引用原始变量,否则总是引用。堆栈上有引用(变量)并不意味着此引用的值不能为Null(该值就是您正在检查的值)。@kai在什么情况下引用会出现,但同时无意中为Null?@user4581301除了不能为字符串分配内存之外,局部变量的引用可能为null的情况有哪些?此外,考虑到不能为字符串分配内存的可能性,为什么字节数组消除了这个问题?发送字节数组可能对“代码>空NU/CODE”的潜力没有帮助,但是它使这些字节转换成<代码>字符串友好字符更容易。总得有人把这个问题的答案写出来。
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);
}
$ javac Test.java
$ javah Test
$ gcc --std=c++11 -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -fPIC -shared -o libTest.so Test.cc
$ /usr/bin/java -Djava.library.path=. Test