英文:
Need assistance with question on java generics
问题
My output is currently:
> Avengers@15db9742 Avengers@6d06d69c
I need to figure out how to display the names as well, using the generic print method. I've been trying things like: GenericMethod_violette.<Avengers>print(avenger.getName())
and GenericMethod_violette.<Avengers>print(avenger.trueIdentity())
but after days on this I seem to be stuck.
My output needs to be:
> Avengers@15db9742 Avengers@6d06d69c
> Tony Stark, Bruce Banner
My GenericMethod_violette.java
:
import java.io.ObjectInputStream.GetField;
public class GenericMethod_violette {
public static void main(String[] args) {
Avengers[] avenger = { new Avengers("Tony Stark"), new Avengers("Bruce Banner")};
GenericMethod_violette.<Avengers>print(avenger);
}
public static <E> void print(E[] list) {
for (int i = 0; i < list.length; i++)
System.out.print(list[i].getName() + " ");
System.out.println();
}
}
My Avengers.java
:
public class Avengers {
private String trueIdentity;
public Avengers(String name) {
trueIdentity = name;
}
public String getName() {
return trueIdentity;
}
public String sayTrueIdentity() {
return "Hello, I'm " + trueIdentity + "!";
}
}
英文:
My output is currently:
> Avengers@15db9742 Avengers@6d06d69c
I need to figure out how to display the names as well, using the generic print method. I've been trying things like: GenericMethod_violette.<Avengers>print(avenger.getName())
and GenericMethod_violette.<Avengers>print(avenger.trueIdentity())
but after days on this I seem to be stuck.
My output needs to be:
> Avengers@15db9742 Avengers@6d06d69c
> Tony Stark, Bruce Banner
My GenericMethod_violette.java
:
import java.io.ObjectInputStream.GetField;
public class GenericMethod_violette {
public static void main(String[] args ) {
Avengers[] avenger = { new Avengers("Tony Stark"), new Avengers("Bruce Banner")};
GenericMethod_violette.<Integer>print(integers);
GenericMethod_violette.<String>print(strings);
GenericMethod_violette.<Avengers>print(avenger);
}
public static <E> void print(E[] list) {
for (int i = 0; i < list.length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
}
My Avengers.java
:
public class Avengers
{
private String trueIdentity;
public Avengers(String name)
{
trueIdentity = name;
}
public String getName()
{
return trueIdentity;
}
public String sayTrueIdentity()
{
return "Hello, I'm " + trueIdentity + "!";
}
}
答案1
得分: 1
你可以在Avengers类中使用toString方法:
public class Avengers {
private String trueIdentity;
public Avengers(String name) {
trueIdentity = name;
}
public String getName() {
return trueIdentity;
}
public String sayTrueIdentity() {
return "Hello, I'm " + trueIdentity + "!";
}
@Override
public String toString() {
return this.getName() + this.sayTrueIdentity();
}
}
然后将你的GenericMethod_violette.print方法修改为使用toString():
public static <E> void print(E[] list) {
for (int i = 0; i < list.length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
Avengers打印格式的原因 - Avengers@15db9742
在Java中,所有对象都有一个toString()方法,当你尝试打印对象时会调用该方法。
System.out.println(myObject); // 调用myObject.toString()
这个方法在Object类中定义(所有Java对象的超类)。Object.toString()方法返回一个相当不好看的字符串,由类名、@符号和对象的十六进制哈希码组成。该方法的代码如下:
// Object.toString()的代码
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
因此,你需要使用@override来重写toString方法。
英文:
you can use write toString inside Avengers
public class Avengers
{
private String trueIdentity;
public Avengers(String name)
{
trueIdentity = name;
}
public String getName()
{
return trueIdentity;
}
public String sayTrueIdentity()
{
return "Hello, I'm " + trueIdentity + "!";
}
// write any format you want to print
@override
public String toString()
{
return this.getName() + this.sayTrueIdentity();
}
}
then change your GenericMethod_violette.print method to use toString()
public static <E> void print(E[] list) {
for (int i = 0; i < list.length; i++)
System.out.print(list[i] + " ");
System.out.println();
}
Reason for Avengers print format - Avengers@15db9742
In java all objects have a toString() method, which is invoked when you try and print the object.
System.out.println(myObject); // invokes myObject.toString()
This method is defined in the Object class (the superclass of all Java objects). The Object.toString() method returns a fairly ugly looking string, composed of the name of the class, an @ symbol and the hashcode of the object in hexadecimal. The code for this looks like:
// Code of Object.toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
So you need @overrride toString method.
答案2
得分: 0
你对 Avengers@15db9742
的打印结果表明它是一个你打印出来的对象。如果你想打印出有意义的信息,你需要重写该对象的 toString()
方法。在这种情况下,是你的 Avengers
对象。
public String toString(){
return trueIdentity;
}
从 @markspace 的注释中添加了关于 java toString() 的说明。
英文:
Your print result of Avengers@15db9742
would mean that it is an object that you printed. If you want to print something meaningful, you need to override the toString()
method of said object. In this case, of your Avengers
object.
public String toString(){
return trueIdentity;
}
> Added notes from @markspace of java toString().
答案3
得分: 0
类Avengers
没有覆盖Object::toString
方法,而System.out.println
在其实现中隐式使用了这个方法。建议您阅读更多信息:https://stackoverflow.com/questions/10734106/how-to-override-tostring-properly-in-java。
然而,此解决方案要求传递给该方法的所有可能对象都必须覆盖此方法,这是无法保证的。我建议您传递一个Function<E, String>
,以从泛型类型中提取字段作为要打印的String
:
public static <E> void print(E[] array, Function<E, String> extractor) {
for (E e : array) {
System.out.print(extractor.apply(e) + " ");
}
System.out.println();
}
使用非常简单(只要推断出泛型类型,就可以省略泛型类型):
// 以下两行基本相同
GenericMethod_violette.print(avenger, a -> a.getName());
GenericMethod_violette.print(avenger, Avenger::getName);
// 如果Avengers有更多字段或需要自定义,例如:
GenericMethod_violette.print(avenger, a -> "Mr. " + a.getName().toUpperCase());
**免责声明:**此解决方案需要Java 8。如果使用Java 7或更低版本,则必须在所有预期的类中覆盖Object::toString
:
@Override
public String toString() {
return this.getName();
}
英文:
The class Avengers
doesn't override the Object::toString
method which System.out.println
implicitely uses in its implementation. I suggest you to read more at: https://stackoverflow.com/questions/10734106/how-to-override-tostring-properly-in-java.
However, this solution requires all the possible objects passed into the method to override such method, which you cannot guarantee. I recommend you to pass a Function<E, String>
that exctracts from the generic type the field(s) as String
to be printed out:
public static <E> void print(E[] array, Function<E, String> extractor) {
for (E e: array) {
System.out.print(extractor.apply(e) + " ");
}
System.out.println();
}
The usage is fairly simple (the generic type can be omitted as long as it is inferred):
// both following lines are basically identical
GenericMethod_violette.print(avenger, a -> a.getName());
GenericMethod_violette.print(avenger, Avenger::getName);
// if Avengers have more of the fields or they are to be customized, ex.:
GenericMethod_violette.print(avenger, a -> "Mr." + a.getName().toUpperCase());
Disclaimer: This solution requires Java 8. If you use Java 7 or lower, you are stick to override the Object::toString
in all the expected classes:
@Override
public String toString() {
return this.getName();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论