虽然我知道这不是创建哈希码的最有效方法,但我正在努力通过将数据转换为整数来创建哈希码,这将是它们的哈希码。我接近这个只有32位或更少的数据类型(因此只是字节,整数,字符,短和浮点)。在创建程序的过程中,我遇到了一个必须与泛型有关的问题。我有一个类只接受我在上面讨论过的数据类型,在if中使用java中的instanceof关键字:
public class HashCode<T>
{
public static void main(String[]args)
{
codeAsInt(2);
codeAsInt('C');
codeAsInt("name");
}
public int codeAsInt(T value)
{
if(value instanceof Integer || value instanceof Character || value instanceof Short || value instanceof Float || value instanceof Byte)
{
int hashcode = (int)value;
return hashcode;
}
else
{
//you cannot use this method return -1
return -1;
}
}
这样做会导致错误,因为我无法将任何这些类型的“值”转换为T.无论如何,我可以将不同的数据类型传递给使用泛型的方法吗?我知道我可以使用方法重载来解决这个问题(创建接受不同数据类型的不同方法)但是从我学到的方法重载方法与使用不同方法的方法一起使用,对于我的方法它做同样的事情(将数据转换为int) )。我也知道我可以创建一个单独的类来执行此操作,但我认为这对于这么简单的任务来说效率很低。
编译时错误:
error: incompatible types: int cannot be converted to T
codeAsInt(2);
^
where T is a type-variable:
T extends Object declared in class HashCodes
error: incompatible types: char cannot be converted to T
codeAsInt('C');
^
where T is a type-variable:
T extends Object declared in class HashCodes
error: incompatible types: String cannot be converted to T
codeAsInt("name");
^
where T is a type-variable:
T extends Object declared in class HashCodes
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
3 errors
Tool completed with exit code 1
任何帮助都会受到赞赏,以及任何比我正在使用的方法更好的方法。
答案 0 :(得分:1)
我猜错误来自于从静态上下文调用泛型非静态方法。要使代码编译,但不能直接工作;),您应该将main
方法中的调用更改为:
new HashCode<Integer>().codeAsInt(2);
new HashCode<Character>().codeAsInt('C');
new HashCode<String>().codeAsInt("name");
因此,在您的情况下,需要在创建对象时实例化类并指定T
的类型。看来你想让编译器通过参数推断出类型。
Here Oracle提供了有关java的类型推理机制的提示,您可以按如下方式使用您的类。
HashCode<Integer> i = new HashCode<>().codeAsInt(2);
HashCode<Character> c = new HashCode<>().codeAsInt('C');
HashCode<String> s = new HashCode<>().codeAsInt("name");
i.codeAsInt(2);
c.codeAsInt('C');
s.codeAsInt("name");
因此,您可以省略实例化的类型信息,但不能声明声明。我不是100%确定是否可以使用java 1.8的类型推断以更清晰的方式编写它。
从java 1.7及更早版本开始,可以使用java的类型文字来实现类似的功能。但是,您必须始终将该文字明确地传递给该方法。你的全班并没有明确要求是通用的,如果你想在每个单独的方法调用上选择类型,那么只需要一个通用的方法就足够了。
public class SomeClass {
public static <T> int codeAsInt(Class<T> type, T value) {
// here you can use the type object
if(type.isInstance(value)) {
// ...
}
public static void main(String... args) {
codeAsInt(Integer.class, 2);
codeAsInt(Character.class, 'C');
codeAsInt(String.class, "name");
}
}
Class
类型在运行时为您提供了类型T
的对象,因为在编译之后它通常不再可用。使用type
对象,您可以在运行时转换为T
。有一些cast
方法,需要Object
并返回T
。此外,如果对象的类型为T
,则可以使用isInstance
方法进行检查。但是,选择所描述的方法会使类型检查过时,因为如果您不小心将某些内容传递给非T
类型的方法,编译器会通知您。
我仍然不确定你到底在寻找什么,但我希望这会有所帮助。如果您只想动态地将任何类型的对象强制转换为T
,只需直接使用类型文字转换方法。
盲目写作,不对拼写错误或编译错误提供保证;)
答案 1 :(得分:-2)
我认为你在谈论serialization
答案 2 :(得分:-2)
这是一个使用反射的类,你必须处理抛出的异常并管理它们:
public class Test {
public static void main(String[] args) { // Manage command line argument
try
{
System.out.println(getHashCode("java.lang.String", "10")); // For simplicity
}
catch(Exception e)
{
System.err.println("There's a problem with this test ! Here is the details :\n"+e.getMessage());
}
}
public static int getHashCode(String className, String value) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class<?> clazz = Class.forName(className);
Constructor<?> c = clazz.getConstructor(String.class);
Object o = c.newInstance(value);
return o.hashCode();
}
}