Coder Social home page Coder Social logo

Comments (2)

mangstadt avatar mangstadt commented on August 26, 2024

Yes, the problem does occur in plain Java! Thank you for pointing that out.

That code sample from the FAQ only works if you leave out the generics and ignore the type safety warnings.

In fact, similar code is used by the writer classes (VCardWriter, JCardWriter, etc). Generics are left out of the VCardPropertyScribe scribe variable declaration. A method-level annotation is used to suppress the warnings.

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void _write(VCard vcard, List<VCardProperty> properties) throws IOException {
  //...
  for (VCardProperty property : propertiesToAdd) {
    VCardPropertyScribe scribe = index.getPropertyScribe(property);
    String value = scribe.writeText(property, context);
    //...
  }
 //...
}

I understand why the compiler has a problem with this. The compiler has no way of knowing that the VCardPropertyScribe implementation correctly corresponds with the given VCardProperty implementation. For example, in the code below, a FormattedName property object is passed into a AddressPropertyScribe object. The compiler gives several warnings, but allows the code to be compiled and run. When the code is run, the last line throws a ClassCastException because it is trying to cast the FormattedName object to an Address object.

ScribeIndex index = new ScribeIndex();
WriteContext context = new WriteContext(VCardVersion.V3_0, null, true);
VCardProperty property = new FormattedName("value");
VCardPropertyScribe scribe = index.getPropertyScribe(Address.class); //compiler: raw type warning
String value = scribe.writeText(property, context); //compiler: type safety warning; ClassCastException thrown at runtime

ez-vcard never throws this exception because the code is written such that the property object that is passed into the index.getPropertyScribe method is ALSO passed into the scribe.writeText method. It's never a different object, as it is in the failing code sample above.

One potential fix is to change the method signature of VCardPropertyScribe.writeText to accept a VCardProperty object instead of a <T extends VCardProperty> object. However, doing that prevents the scribe classes from being able to use their corresponding property classes in each of their "write" methods (e.g. using the Address class in the AddressPropertyScribe.writeText method signature.

At the moment, I am not sure what else can be done to resolve this. I am open to ideas of course!

from ez-vcard.

rfc2822 avatar rfc2822 commented on August 26, 2024

Thanks for your explanations! I have found how to do the same unchecked conversion with Kotlin:

val vCard: VCard
val scribeIndex = ScribeIndex()
for (prop in vCard.properties) {
    // prop is now of type VCardProperty
        
    @Suppress("UNCHECKED_CAST")
    val scribe = scribeIndex.getPropertyScribe(prop) as VCardPropertyScribe<VCardProperty>
    // scribe is now of type VCardPropertyScribe<VCardProperty> 
    
    scribe.writeJson(prop)       // works!
}

from ez-vcard.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.